// ==UserScript==
// @name GitHub warehouse quick jump assistant
// @description 🤠 GitHub warehouse quick jump assistant, specially designed to help users quickly access their own warehouses on GitHub. It generates a button at the top of the navigation bar. Click to expand all your repositories and easily jump to your own GitHub repository page without using GitHub’s secondary menu.
// @name:zh-CN GitHub 仓库快速跳转助手
// @description:zh-CN 🤠 GitHub 仓库快速跳转助手,专为帮助用户快速访问自己在 GitHub 上的仓库而设计 。它在导航栏顶部生成一个按钮,点击展开自己的所有仓库,轻松跳转到自己的 GitHub 仓库页面,而无需使用 GitHub 的二级菜单
// @name:ar مساعد القفز السريع لمستودع GitHub
// @description:ar 🤠 مساعد القفز السريع لمستودعات GitHub، مصمم خصيصًا لمساعدة المستخدمين على الوصول بسرعة إلى مستودعاتهم الخاصة على GitHub. يقوم بإنشاء زر أعلى شريط التنقل. انقر لتوسيع جميع مستودعاتك والانتقال بسهولة إلى صفحة مستودع GitHub الخاصة بك دون استخدام قائمة GitHub الثانوية.
// @name:bg Асистент за бързо прескачане в склада на GitHub
// @description:bg 🤠 Асистент за бързо прескачане на склад GitHub, специално проектиран да помага на потребителите бързо да имат достъп до собствените си складове в GitHub. Той генерира бутон в горната част на навигационната лента, за да разгънете всичките си хранилища и лесно да преминете към страницата на вашето собствено хранилище на GitHub, без да използвате второстепенното меню на GitHub.
// @name:cs Asistent rychlého skoku ve skladu GitHub
// @description:cs 🤠 Asistent rychlého skoku do skladu GitHub, speciálně navržený tak, aby uživatelům pomohl rychle získat přístup k vlastním skladům na GitHubu. Vygeneruje tlačítko v horní části navigačního panelu Kliknutím rozbalíte všechna úložiště a snadno přejdete na stránku vlastního úložiště GitHub bez použití sekundární nabídky GitHubu.
// @name:da GitHub-lagerets hurtigspringsassistent
// @description:da 🤠 GitHub warehouse quick jump assistent, specielt designet til at hjælpe brugere med hurtigt at få adgang til deres egne varehuse på GitHub. Den genererer en knap øverst på navigationslinjen Klik for at udvide alle dine lagre og nemt springe til din egen GitHub-lagerside uden at bruge GitHubs sekundære menu.
// @name:de GitHub Warehouse-Schnellsprungassistent
// @description:de 🤠 GitHub-Warehouse-Schnellsprung-Assistent, der speziell entwickelt wurde, um Benutzern den schnellen Zugriff auf ihre eigenen Warehouses auf GitHub zu erleichtern. Es generiert eine Schaltfläche oben in der Navigationsleiste. Klicken Sie darauf, um alle Ihre Repositorys zu erweitern und einfach zu Ihrer eigenen GitHub-Repository-Seite zu springen, ohne das sekundäre Menü von GitHub zu verwenden.
// @name:el Βοηθός γρήγορου άλματος αποθήκης GitHub
// @description:el 🤠 Βοηθός γρήγορου άλματος αποθήκης GitHub, ειδικά σχεδιασμένος για να βοηθά τους χρήστες να έχουν γρήγορη πρόσβαση στις δικές τους αποθήκες στο GitHub. Δημιουργεί ένα κουμπί στο επάνω μέρος της γραμμής πλοήγησης Κάντε κλικ για να επεκτείνετε όλα τα αποθετήρια σας και να μεταβείτε εύκολα στη δική σας σελίδα αποθετηρίου GitHub χωρίς να χρησιμοποιήσετε το δευτερεύον μενού του GitHub.
// @name:en GitHub warehouse quick jump assistant
// @description:en 🤠 GitHub warehouse quick jump assistant, specially designed to help users quickly access their own warehouses on GitHub. It generates a button at the top of the navigation bar. Click to expand all your repositories and easily jump to your own GitHub repository page without using GitHub’s secondary menu.
// @name:eo GitHub magazena rapida salta asistanto
// @description:eo 🤠 GitHub magazena rapida salta asistanto, speciale desegnita por helpi uzantojn rapide aliri siajn proprajn stokejojn sur GitHub. Ĝi generas butonon ĉe la supro de la navigadbreto Alklaku por vastigi ĉiujn viajn deponejojn kaj facile salti al via propra GitHub-deponeja paĝo sen uzi la sekundaran menuon de GitHub.
// @name:es Asistente de salto rápido del almacén de GitHub
// @description:es 🤠 Asistente de salto rápido del almacén de GitHub, especialmente diseñado para ayudar a los usuarios a acceder rápidamente a sus propios almacenes en GitHub. Genera un botón en la parte superior de la barra de navegación. Haga clic para expandir todos sus repositorios y saltar fácilmente a su propia página de repositorio de GitHub sin usar el menú secundario de GitHub.
// @name:fi GitHub-varaston pikahypyn avustaja
// @description:fi 🤠 GitHub-varaston pika-apulainen, joka on erityisesti suunniteltu auttamaan käyttäjiä pääsemään nopeasti omiin varastoihinsa GitHubissa. Se luo painikkeen navigointipalkin yläosaan. Napsauta laajentaaksesi kaikki tietovarastot ja siirtyäksesi helposti omalle GitHub-tietovarastosivullesi ilman GitHubin toissijaista valikkoa.
// @name:fr Assistant de saut rapide de l’entrepôt GitHub
// @description:fr 🤠 Assistant de saut rapide d’entrepôt GitHub, spécialement conçu pour aider les utilisateurs à accéder rapidement à leurs propres entrepôts sur GitHub. Il génère un bouton en haut de la barre de navigation. Cliquez pour développer tous vos référentiels et accéder facilement à votre propre page de référentiel GitHub sans utiliser le menu secondaire de GitHub.
// @name:he עוזר קפיצה מהירה במחסן GitHub
// @description:he 🤠 עוזר קפיצה מהירה במחסן GitHub, תוכנן במיוחד כדי לעזור למשתמשים לגשת במהירות למחסנים שלהם ב-GitHub. זה יוצר כפתור בחלק העליון של סרגל הניווט לחץ כדי להרחיב את כל המאגרים שלך ולקפוץ בקלות לדף מאגר GitHub שלך מבלי להשתמש בתפריט המשני של GitHub.
// @name:hr Pomoćnik za brzi skok u skladište GitHub
// @description:hr 🤠 Pomoćnik za brzi skok u skladište GitHub, posebno dizajniran da pomogne korisnicima da brzo pristupe vlastitim skladištima na GitHubu. Generira gumb na vrhu navigacijske trake Kliknite da biste proširili sva svoja spremišta i jednostavno skočili na svoju stranicu GitHub spremišta bez korištenja sekundarnog izbornika GitHuba.
// @name:hu GitHub raktári gyorsugrási asszisztens
// @description:hu 🤠 GitHub raktári gyorsugrási asszisztens, amelyet kifejezetten arra terveztek, hogy a felhasználók gyorsan hozzáférhessenek saját raktáraikhoz a GitHubon. Létrehoz egy gombot a navigációs sáv tetején. Kattintson az összes adattár kibontásához, és egyszerűen a GitHub másodlagos menüjének használata nélkül ugorjon a saját GitHub adattároldalára.
// @name:id Asisten lompat cepat gudang GitHub
// @description:id 🤠 Asisten lompat cepat gudang GitHub, dirancang khusus untuk membantu pengguna mengakses gudang mereka sendiri dengan cepat di GitHub. Ini menghasilkan tombol di bagian atas bilah navigasi. Klik untuk memperluas semua repositori Anda dan dengan mudah melompat ke halaman repositori GitHub Anda sendiri tanpa menggunakan menu sekunder GitHub.
// @name:it Assistente di salto rapido del magazzino GitHub
// @description:it 🤠 Assistente di salto rapido del magazzino GitHub, appositamente progettato per aiutare gli utenti ad accedere rapidamente ai propri magazzini su GitHub. Genera un pulsante nella parte superiore della barra di navigazione. Fai clic per espandere tutti i tuoi repository e passare facilmente alla pagina del tuo repository GitHub senza utilizzare il menu secondario di GitHub.
// @name:ja GitHub ウェアハウスのクイック ジャンプ アシスタント
// @description:ja 🤠 GitHub ウェアハウス クイック ジャンプ アシスタント。ユーザーが GitHub 上の自分のウェアハウスにすばやくアクセスできるように特別に設計されています。ナビゲーション バーの上部にボタンが生成され、クリックするとすべてのリポジトリが展開され、GitHub の 2 番目のメニューを使用せずに独自の GitHub リポジトリ ページに簡単にジャンプできます。
// @name:ka GitHub საწყობის სწრაფი ნახტომის ასისტენტი
// @description:ka 🤠 GitHub საწყობის სწრაფი გადახტომის ასისტენტი, სპეციალურად შექმნილი, რათა დაეხმაროს მომხმარებლებს სწრაფად წვდომა საკუთარ საწყობებზე GitHub-ზე. ის ქმნის ღილაკს ნავიგაციის ზოლის ზედა ნაწილში.
// @name:ko GitHub 창고 빠른 점프 도우미
// @description:ko 🤠 GitHub 창고 빠른 점프 도우미는 사용자가 GitHub에서 자신의 창고에 빠르게 액세스할 수 있도록 특별히 설계되었습니다. 탐색 모음 상단에 버튼이 생성됩니다. 클릭하면 모든 저장소가 확장되고 GitHub의 보조 메뉴를 사용하지 않고도 자신의 GitHub 저장소 페이지로 쉽게 이동할 수 있습니다.
// @name:nl GitHub magazijn snelle sprong-assistent
// @description:nl 🤠 GitHub magazijn snelle sprong-assistent, speciaal ontworpen om gebruikers te helpen snel toegang te krijgen tot hun eigen magazijnen op GitHub. Het genereert een knop bovenaan de navigatiebalk. Klik om al je repository’s uit te vouwen en eenvoudig naar je eigen GitHub-repositorypagina te gaan zonder het secundaire menu van GitHub te gebruiken.
// @name:nb GitHub-varehus hurtighoppassistent
// @description:nb 🤠 GitHub-varehus-hurtighoppassistent, spesialdesignet for å hjelpe brukere raskt å få tilgang til sine egne varehus på GitHub. Den genererer en knapp på toppen av navigasjonslinjen Klikk for å utvide alle lagrene dine og enkelt hoppe til din egen GitHub-depotside uten å bruke GitHubs sekundære meny.
// @name:pl Asystent szybkiego skoku do magazynu GitHub
// @description:pl 🤠 Asystent szybkiego skoku do magazynu GitHub, specjalnie zaprojektowany, aby pomóc użytkownikom szybko uzyskać dostęp do własnych magazynów w GitHub. Generuje przycisk na górze paska nawigacyjnego. Kliknij, aby rozwinąć wszystkie swoje repozytoria i łatwo przejść do własnej strony repozytorium GitHub bez korzystania z dodatkowego menu GitHub.
// @name:pt-BR Assistente de salto rápido do GitHub Warehouse
// @description:pt-BR 🤠 Assistente de salto rápido do GitHub Warehouse, especialmente projetado para ajudar os usuários a acessar rapidamente seus próprios armazéns no GitHub. Ele gera um botão na parte superior da barra de navegação. Clique para expandir todos os seus repositórios e ir facilmente para a página do seu próprio repositório GitHub sem usar o menu secundário do GitHub.
// @name:ro GitHub warehouse quick jump assistant
// @description:ro 🤠 GitHub warehouse quick jump assistant, special conceput pentru a ajuta utilizatorii să-și acceseze rapid propriile depozite pe GitHub. Acesta generează un buton în partea de sus a barei de navigare Faceți clic pentru a vă extinde toate depozitele și pentru a sări cu ușurință la propria pagină de depozit GitHub, fără a utiliza meniul secundar al GitHub.
// @name:ru Помощник по быстрому переходу на склад GitHub
// @description:ru 🤠 Помощник по быстрому переходу на склады GitHub, специально разработанный, чтобы помочь пользователям быстро получить доступ к собственным складам на GitHub. Он создает кнопку в верхней части панели навигации. Нажмите, чтобы развернуть все ваши репозитории и легко перейти на страницу собственного репозитория GitHub, не используя вторичное меню GitHub.
// @name:sk Asistent rýchleho skoku do skladu GitHub
// @description:sk 🤠 Asistent rýchleho skoku do skladu GitHub, špeciálne navrhnutý tak, aby pomohol používateľom rýchlo získať prístup k vlastným skladom na GitHub. Vygeneruje tlačidlo v hornej časti navigačného panela. Kliknutím rozbalíte všetky svoje úložiská a jednoducho prejdete na svoju vlastnú stránku úložiska GitHub bez použitia sekundárnej ponuky GitHub.
// @name:sr ГитХуб помоћник за брзи скок у складишту
// @description:sr 🤠 ГитХуб помоћник за брзо прескакање складишта, специјално дизајниран да помогне корисницима да брзо приступе сопственим складиштима на ГитХуб-у. Генерише дугме на врху траке за навигацију. Кликните да бисте проширили сва своја спремишта и лако прешли на своју страницу ГитХуб спремишта без коришћења секундарног менија ГитХуб-а.
// @name:sv GitHub lager snabbhoppsassistent
// @description:sv 🤠 GitHub lager snabbhoppsassistent, speciellt designad för att hjälpa användare att snabbt komma åt sina egna lager på GitHub. Den genererar en knapp högst upp i navigeringsfältet Klicka för att expandera alla dina förråd och enkelt hoppa till din egen GitHub-förrådssida utan att använda GitHubs sekundära meny.
// @name:th GitHub ผู้ช่วยกระโดดด่วนคลังสินค้า
// @description:th 🤠 ตัวช่วยกระโดดด่วนคลังสินค้า GitHub ออกแบบมาเป็นพิเศษเพื่อช่วยให้ผู้ใช้เข้าถึงคลังสินค้าของตนเองบน GitHub ได้อย่างรวดเร็ว โดยจะสร้างปุ่มที่ด้านบนของแถบนำทาง คลิกเพื่อขยายพื้นที่เก็บข้อมูลทั้งหมดของคุณและข้ามไปยังหน้าพื้นที่เก็บข้อมูล GitHub ของคุณได้อย่างง่ายดายโดยไม่ต้องใช้เมนูรองของ GitHub
// @name:tr GitHub deposu hızlı atlama asistanı
// @description:tr 🤠 GitHub depo hızlı atlama asistanı, kullanıcıların GitHub’da kendi depolarına hızlı bir şekilde erişmelerine yardımcı olmak için özel olarak tasarlanmıştır. Gezinme çubuğunun üst kısmında bir düğme oluşturur. Tüm depolarınızı genişletmek ve GitHub’un ikincil menüsünü kullanmadan kendi GitHub depo sayfanıza kolayca atlamak için tıklayın.
// @name:ug GitHub ئامبىرى تېز سەكرەش ياردەمچىسى
// @description:ug It GitHub ئامبىرىنىڭ تېز سەكرەش ياردەمچىسى ، ئالاھىدە لايىھەلەنگەن بولۇپ ، ئابونتلارنىڭ GitHub دىكى ئامبارلىرىغا تېزرەك كىرىشىگە ياردەم بېرىدۇ. ئۇ يولباشچى ستونىنىڭ ئۈستى تەرىپىدە بىر كۇنۇپكا ھاسىل قىلىدۇ ، بارلىق ئامبارلىرىڭىزنى كېڭەيتىپ ، GitHub نىڭ ئىككىلەمچى تىزىملىكىنى ئىشلەتمەي تۇرۇپلا ئۆزىڭىزنىڭ GitHub ئامبىرى بېتىگە سەكرەپ چىقىڭ.
// @name:uk Помічник швидкого переходу зі складу GitHub
// @description:uk 🤠 Помічник швидкого переходу зі складу GitHub, спеціально розроблений, щоб допомогти користувачам швидко отримати доступ до власних складів на GitHub. Він генерує кнопку у верхній частині навігаційної панелі, щоб розгорнути всі ваші сховища та легко перейти до власної сторінки сховища GitHub без використання додаткового меню GitHub.
// @name:vi Trợ lý nhảy nhanh kho GitHub
// @description:vi 🤠 Trợ lý nhảy nhanh kho GitHub, được thiết kế đặc biệt để giúp người dùng truy cập nhanh vào kho của họ trên GitHub. Nó tạo ra một nút ở đầu thanh điều hướng. Nhấp để mở rộng tất cả các kho lưu trữ của bạn và dễ dàng chuyển đến trang kho lưu trữ GitHub của riêng bạn mà không cần sử dụng menu phụ của GitHub.
// @name:zh-SG GitHub 仓库快速跳转助手
// @description:zh-SG 🤠 GitHub 仓库快速跳转助手,专为帮助用户快速访问自己在 GitHub 上的仓库而设计 。它在导航栏顶部生成一个按钮,点击展开自己的所有仓库,轻松跳转到自己的 GitHub 仓库页面,而无需使用 GitHub 的二级菜单
// @name:zh GitHub 仓库快速跳转助手
// @description:zh 🤠 GitHub 仓库快速跳转助手,专为帮助用户快速访问自己在 GitHub 上的仓库而设计 。它在导航栏顶部生成一个按钮,点击展开自己的所有仓库,轻松跳转到自己的 GitHub 仓库页面,而无需使用 GitHub 的二级菜单
// @name:zh-TW GitHub 倉庫快速跳轉助手
// @description:zh-TW 🤠 GitHub 倉庫快速跳轉助手,專為幫助用戶快速存取自己在 GitHub 上的倉庫而設計 。它在導覽列頂部產生一個按鈕,點擊展開自己的所有倉庫,輕鬆跳到自己的 GitHub 倉庫頁面,而無需使用 GitHub 的二級選單
// @name:zh-HK GitHub 倉庫快速跳轉助手
// @description:zh-HK 🤠 GitHub 倉庫快速跳轉助手,專為幫助用戶快速存取自己在 GitHub 上的倉庫而設計 。它在導覽列頂部產生一個按鈕,點擊展開自己的所有倉庫,輕鬆跳到自己的 GitHub 倉庫頁面,而無需使用 GitHub 的二級選單
// @name:fr-CA Assistant de saut rapide de l’entrepôt GitHub
// @description:fr-CA 🤠 Assistant de saut rapide d’entrepôt GitHub, spécialement conçu pour aider les utilisateurs à accéder rapidement à leurs propres entrepôts sur GitHub. Il génère un bouton en haut de la barre de navigation.
// @namespace https://github.com/ChinaGodMan/UserScripts
// @version 2024.11.6.21
// @author mshll & 人民的勤务员 <[email protected]>
// @match https://github.com/*
// @grant none
// @run-at document-start
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @grant none
// @require https://update.greasyfork.org/scripts/511697/1460281/TOTP%20Generator.js
// @icon data:image/png;base64,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
// @iconbak https://github.githubassets.com/pinned-octocat.svg
// @license MIT
// @source https://github.com/qinwuyuan-cn/UserScripts
// @run-at document-start
// @supportURL https://github.com/ChinaGodMan/UserScripts/issues
// @homepageURL https://github.com/ChinaGodMan/UserScripts
// ==/UserScript==
'use strict'
const userLang =
(navigator.languages && navigator.languages[0]) ||
navigator.language ||
'en'
const translations = {
en: {
save: 'Save',
cancel: 'Cancel',
modaltitle: 'Set GitHub Token',
description: 'Enter your GitHub personal access token with "repo" scope.',
githubtokeninput: 'Enter your GitHub personal access token',
newtoken: 'Click here to create a new token',
warncheckbox: ' Inactive Development Warning',
menu: 'Set GitHub Token',
renderWarning: 'WARNING: repo has not received an update in 1+ year(s)',
renderCaution: 'Caution: repo has not received an update in 6+ months',
confirm: 'You have not entered a Token, confirm to clear the GitHub Token?',
timediff: 'Last commit was: {years} years, {months} months, {days} days ago ',
view: 'View[',
allRepos: ']All repositories',
newTab: 'Open in a new tab when quickly viewing repositories',
repoSize: 'Repository size:',
repoDes: 'Repository description:',
repoLang: 'Primary language:',
repoCreated: 'Initial creation time:',
repoUpdated: 'Last updated:',
repoPushed: 'Last pushed:',
repoForks: 'Forks:',
repoStars: 'Stars:',
ossinsight: 'OSS Insight analysis page for the repository',
activeforks: 'Active forks list for the repository',
activeforks_: 'Active forks',
publicRepos: 'Public repositories: ',
privateRepos: 'Private repositories: ',
forkRepos: 'Forked repositories: ',
deleteRepo_i: 'You are trying to delete the repository:',
deleteRepo: 'ChinaGodMan reminds you:\nDeleting a repository is an extremely dangerous operation.\nOnce you delete a repository, it cannot be recovered.\nPlease think twice! Data is priceless, cherish it.',
deleteRepo_ask: 'Are you sure you want to delete the repository? (Confirmed',
deleteRepo_pass: 'Deletion successful!',
deleteRepo_failed: 'Deletion failed!\nIt is recommended to check whether the GitHub token has permission to delete the repository!',
deleteRepo_failed_status: 'Status code:',
deleteRepo_btn: 'Delete repository',
secret: '[Optional:] Enter your two-factor key for automatic input during GitHub\'s two-step verification.'
},
'zh-CN,zh,zh-SG': {
save: '保存',
cancel: '取消',
modaltitle: '设置 GitHub 令牌',
description: '请输入您的 GitHub 个人访问令牌,需具备 "repo" 权限。',
githubtokeninput: '请输入您的 GitHub 个人访问令牌',
newtoken: '点击此处创建新的令牌',
warncheckbox: ' 非活跃开发警告',
menu: '设置 GitHub 令牌',
renderWarning: '警告:该仓库在 1 年以上未更新',
renderCaution: '注意:该仓库在 6 个月以上未更新',
confirm: '你没有输入Token,确认清空GitHub Token?',
timediff: '最后一次提交距现在:{years}年{months}个月{days}天 ',
view: '查看',
allRepos: '所有仓库',
newTab: '快速查看仓库时新窗口打开',
repoSize: '仓库大小:',
repoDes: '仓库简介:',
repoLang: '主要语言:',
repoCreated: '初始创建时间:',
repoUpdated: '最后一次更新:',
repoPushed: '最后一次推送:',
repoForks: '复刻:',
repoStars: '星标:',
ossinsight: '仓库对应的 OSS Insight 分析页面',
activeforks: '仓库对应的活跃复刻列表',
activeforks_: '活跃的复刻',
publicRepos: '公共仓库: ',
privateRepos: '私有仓库: ',
forkRepos: '分叉仓库: ',
deleteRepo_i: '你正在尝试删除仓库:',
deleteRepo: '人民的勤务员提醒你:\n删除仓库是一个极其危险的操作\n 你一旦删除仓库,将再也无法恢复。\n请三思而后行! 数据无价,且行且珍惜',
deleteRepo_ask: '你确定要删除仓库吗? (已确认',
deleteRepo_pass: ' 删除成功!',
deleteRepo_failed: '删除失败!\n建议检查GitHub token 是否具有删除仓库的权限!',
deleteRepo_failed_status: '状态码:',
deleteRepo_btn: '删除仓库',
secret: '[可选项目:]输入你的双因素密钥用于在GitHub触发二次验证时自动输入'
},
'zh-TW,zh-HK,zh-MO': {
save: '保存',
cancel: '取消',
modaltitle: '設定 GitHub 令牌',
description: '請輸入您的 GitHub 個人訪問令牌,需具備 "repo" 權限。',
githubtokeninput: '請輸入您的 GitHub 個人訪問令牌',
newtoken: '點擊此處創建新的令牌',
warncheckbox: ' 非活躍開發警告',
menu: '設定 GitHub 令牌',
renderWarning: '警告:該倉庫在 1 年以上未更新',
renderCaution: '注意:該倉庫在 6 個月以上未更新',
confirm: '你沒有輸入Token,確認清空GitHub Token?',
timediff: '最後一次提交距現在:{years}年{months}個月{days}天 '
},
vi: {
save: 'Lưu',
cancel: 'Hủy',
modaltitle: 'Đặt Token GitHub',
description: 'Nhập token truy cập cá nhân GitHub của bạn với phạm vi "repo".',
githubtokeninput: 'Nhập token truy cập cá nhân GitHub của bạn',
newtoken: 'Nhấn vào đây để tạo token mới',
warncheckbox: ' Cảnh báo phát triển không hoạt động',
menu: 'Đặt Token GitHub',
renderWarning: 'CẢNH BÁO: kho lưu trữ đã không nhận được cập nhật trong hơn 1 năm',
renderCaution: 'Cảnh báo: kho lưu trữ đã không nhận được cập nhật trong hơn 6 tháng',
confirm: 'Bạn chưa nhập Token, xác nhận xóa GitHub Token?',
timediff: 'Lần commit cuối cách đây: {years} năm, {months} tháng, {days} ngày '
},
ja: {
save: '保存',
cancel: 'キャンセル',
modaltitle: 'GitHubトークンの設定',
description: '「repo」スコープを持つGitHub個人アクセストークンを入力してください。',
githubtokeninput: 'GitHub個人アクセストークンを入力してください',
newtoken: '新しいトークンを作成するにはここをクリックしてください',
warncheckbox: ' 非アクティブ開発警告',
menu: 'GitHubトークンの設定',
renderWarning: '警告:リポジトリは1年以上更新されていません',
renderCaution: '注意:リポジトリは6ヶ月以上更新されていません',
confirm: 'トークンが入力されていません。GitHubトークンをクリアしてもよろしいですか?',
timediff: '最終コミットから現在まで:{years}年{months}ヶ月{days}日 '
},
ko: {
save: '저장',
cancel: '취소',
modaltitle: 'GitHub 토큰 설정',
description: '“repo” 범위를 가진 GitHub 개인 액세스 토큰을 입력하세요.',
githubtokeninput: 'GitHub 개인 액세스 토큰을 입력하세요',
newtoken: '여기를 클릭하여 새 토큰을 만드세요',
warncheckbox: ' 비활성 개발 경고',
menu: 'GitHub 토큰 설정',
renderWarning: '경고: 이 저장소는 1년 이상 업데이트되지 않았습니다',
renderCaution: '주의: 이 저장소는 6개월 이상 업데이트되지 않았습니다',
confirm: '토큰을 입력하지 않았습니다. GitHub 토큰을 지우시겠습니까?',
timediff: '마지막 커밋 이후 경과: {years}년 {months}개월 {days}일 '
}
}
const getTranslations = (lang) => {
for (const key in translations) {
if (key === lang || key.split(',').includes(lang)) {
return translations[key]
}
}
return translations['en']
}
const translate = new Proxy(
function (key) {
const lang = userLang
const strings = getTranslations(lang)
return strings[key] || translations['en'][key]
},
{
get(target, prop) {
const lang = userLang
const strings = getTranslations(lang)
return strings[prop] || translations['en'][prop]
}
}
)
let TOKEN = GM_getValue('githubToken', '')
let openInNewTab = GM_getValue('openInNewTab', false)
let DELAY = GM_getValue('DELAY', '24h')
let USETIP = GM_getValue('USETIP', false)//为真时使用GitHub自带的TIP提示而不是用网页title
GM_addStyle(`
.modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);display:flex;justify-content:center;align-items:center;z-index:1000;}
.modal-content{background:white;padding:20px;border-radius:8px;width:400px;box-shadow:0 4px 15px rgba(0,0,0,0.2);position:relative;}
.modal-title{margin:0 0 10px 0;font-size:20px;}
.modal-description{margin-bottom:20px;font-size:14px;color:#666;}
.modal-description a{color:#007bff;text-decoration:underline;}
.github-token-input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;margin-bottom:20px;font-size:14px;}
#save-token{background-color:#28a745;color:white;border:none;padding:10px 20px;cursor:pointer;border-radius:4px;margin-right:10px;}
#cancel-token{background-color:#dc3545;color:white;border:none;padding:10px 20px;cursor:pointer;border-radius:4px;}
`)
function createModal() {
const modalHTML = `
<div class="modal-overlay">
<div class="modal-content">
<h3 class="modal-title">${translate.modaltitle}</h3>
<p class="modal-description">
${translate.description}
<a href="https://github.com/settings/tokens/new?description=GitHub%20Repo%20Size%20UserScript&scopes=repo" target="_blank" rel="noopener noreferrer">
${translate.newtoken}
</a>
</p>
<input type="text" id="github-token-input" placeholder="${translate.githubtokeninput}">
<li role="presentation" aria-hidden="true" data-view-component="true" class="ActionList-sectionDivider"></li>
<button id="save-token">${translate.save}</button>
<button id="cancel-token" class="cancel">${translate.cancel}</button>
</div>
</div>
`
const modalContainer = document.createElement('div')
modalContainer.innerHTML = modalHTML
document.body.appendChild(modalContainer)
const elements = {
input: modalContainer.querySelector('#github-token-input'),
saveButton: modalContainer.querySelector('#save-token'),
cancelButton: modalContainer.querySelector('#cancel-token')
}
elements.input.value = GM_getValue('githubToken', '')
elements.saveButton.addEventListener('click', () => {
const token = elements.input.value.trim()
if (token) {
GM_setValue('githubToken', token)
modalContainer.remove()
TOKEN = token
} else {
const userConfirmed = confirm(translate('confirm')) //提示是否删除
if (userConfirmed) {
GM_setValue('githubToken', token)
modalContainer.remove()
TOKEN = token
}
}
})
elements.cancelButton.addEventListener('click', () => modalContainer.remove())
}
GM_registerMenuCommand(translate('menu'), function () {
createModal()
})
document.addEventListener('DOMContentLoaded', () => {
main()
})
observeUrlChanges(main)
function main(delay = 0) {
waitForElement('#global-create-menu-anchor', false)//
.then(() => {
if (!document.querySelector('#view-global-user-repos')) {
const headers = TOKEN ? { authorization: `token ${TOKEN}` } : {}
const metaElement = document.querySelector('meta[name="octolytics-actor-login"]')
const loginUserName = metaElement.getAttribute('content')
const targetSelector = isMobileDevice() ? '.AppHeader-search button' : '#global-create-menu-anchor'
fetchReposWithCache(loginUserName, 'https://api.github.com/user/repos', headers)
}
})
}
function observeUrlChanges(callback, delay = 10) {
let lastUrl = location.href
const observer = new MutationObserver(() => {
const url = location.href
if (url !== lastUrl) {
lastUrl = url
setTimeout(() => {
callback()
}, delay)
}
})
observer.observe(document, { subtree: true, childList: true })
return observer
}
function waitForElement(selector, dis = true) {
return new Promise((resolve, reject) => {
const observer = new MutationObserver(() => {
if (document.querySelector(selector)) {
resolve()
observer.disconnect()
}
})
if (dis) {
const timeout = setTimeout(() => {
observer.disconnect()
reject(new Error('超时:未找到指定元素'))
}, 10000)
}
observer.observe(document.body, { childList: true, subtree: true })
})
}
function insertReposList(links, tip = false) {
const gitHubStyle = `
#view-global-user-repos {
order: 10;
}
#view-global-user-repos .dropdown-menu {
min-width: 170px;
width: auto;
}
#view-global-user-repos .dropdown-menu .dropdown-item .d-inline-flex {
vertical-align:sub;
`
//
if (!document.head.querySelector('style[data-id="view-global-user-repos-css"]')) {
const globalStyle = document.createElement('style')
globalStyle.dataset.id = 'view-user-repos-css'
globalStyle.innerHTML = gitHubStyle
document.head.appendChild(globalStyle)
}
const targetSelector = isMobileDevice() ? '.AppHeader-search button' : '#global-create-menu-anchor'
const existingButton = document.querySelector(targetSelector)
existingButton.parentNode.style.display = 'flex'
if (existingButton) {
const sortedLinks = links.sort((a, b) => {//!SECTION 排序
// 首先比较 fork 下沉到数组的低端.
if (b.fork > 0 && a.fork <= 0) {
return -1 // a 在前
} else if (a.fork > 0 && b.fork <= 0) {
return 1 // b 在前
} else {
// 如果 fork 相同,比较 private
if (b.private === a.private) {
// 如果 private 相同,进一步判断 private 为 false 的情况
if (!a.private && !b.private) {
return b.stargazers_count - a.stargazers_count // stargazers_count 大的在前
}
return 0 // private 相同且不是 false 的情况下不排序
}
return (b.private ? -1 : 1) // private 为 true 的在前
}
})
function getIconPath(link) {
var fillColor = null
if (link.private) fillColor = 'green'
if (!link.private && !link.fork) fillColor = 'red'
var svg = `<path fill="${fillColor}" fill-rule="evenodd" d="M1 3.5c0-.626.292-1.165.7-1.59.406-.422.956-.767 1.579-1.041C4.525.32 6.195 0 8 0c1.805 0 3.475.32 4.722.869.622.274 1.172.62 1.578 1.04.408.426.7.965.7 1.591v9c0 .626-.292 1.165-.7 1.59-.406.422-.956.767-1.579 1.041C11.476 15.68 9.806 16 8 16c-1.805 0-3.475-.32-4.721-.869-.623-.274-1.173-.62-1.579-1.04-.408-.426-.7-.965-.7-1.591Zm1.5 0c0 .133.058.318.282.551.227.237.591.483 1.101.707C4.898 5.205 6.353 5.5 8 5.5c1.646 0 3.101-.295 4.118-.742.508-.224.873-.471 1.1-.708.224-.232.282-.417.282-.55 0-.133-.058-.318-.282-.551-.227-.237-.591-.483-1.101-.707C11.102 1.795 9.647 1.5 8 1.5c-1.646 0-3.101.295-4.118.742-.508.224-.873.471-1.1.708-.224.232-.282.417-.282.55Zm0 4.5c0 .133.058.318.282.551.227.237.591.483 1.101.707C4.898 9.705 6.353 10 8 10c1.646 0 3.101-.295 4.118-.742.508-.224.873-.471 1.1-.708.224-.232.282-.417.282-.55V5.724c-.241.15-.503.286-.778.407C11.475 6.68 9.805 7 8 7c-1.805 0-3.475-.32-4.721-.869a6.15 6.15 0 0 1-.779-.407Zm0 2.225V12.5c0 .133.058.318.282.55.227.237.592.484 1.1.708 1.016.447 2.471.742 4.118.742 1.647 0 3.102-.295 4.117-.742.51-.224.874-.47 1.101-.707.224-.233.282-.418.282-.551v-2.275c-.241.15-.503.285-.778.406-1.247.549-2.917.869-4.722.869-1.805 0-3.475-.32-4.721-.869a6.327 6.327 0 0 1-.779-.406Z"></path>`
if (fillColor) return svg
if (link.fork) return '<path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path>'
}
let privateClassAdded = false
let forkClassAdded = false
const stats = {
privateTrue: 0,
privateFalse: 0,
forkTrue: 0,
forkFalse: 0
}
const listItems = sortedLinks.map(link => {
stats.privateTrue += (link.private && !link.fork) ? 1 : 0
stats.privateFalse += (link.private ? 0 : 1) && !link.fork ? 1 : 0
stats.forkTrue += link.fork ? 1 : 0
stats.forkFalse += link.fork ? 0 : 1
let liClass = ''
if (link.private && !privateClassAdded) {
liClass += 'border-top'
privateClassAdded = true
}
if (link.fork && !forkClassAdded) {
liClass += 'border-top'
forkClassAdded = true
}
const starsAndForks = [
link.stargazers_count > 0 ? `${translate.repoStars}${link.stargazers_count}` : '',
link.forks_count > 0 ? `${translate.repoForks}${link.forks_count}` : ''
].filter(Boolean).join(' ')
const repoInfo = [
(link.description ? `${translate.repoDes}${link.description}` : ''),
starsAndForks,
`${translate.repoSize}${getHumanReadableSize(link.size)}`,
link.language ? `${translate.repoLang}${link.language}` : '',
`${translate.repoCreated}${link.created_at}`,
`${translate.repoUpdated}${link.updated_at}`,
`${translate.repoPushed}${link.pushed_at}`
].filter(Boolean).join('\n')
return `
<li class="${liClass}${(tip) ? ' tooltipped tooltipped-s' : ''}" aria-label="${repoInfo}">
<a href="${link.html_url}" class="dropdown-item" ${(openInNewTab) ? 'target="_blank"' : ''} rel="noopener noreferrer" ${(tip) ? '"' : ` title="${repoInfo}"`}>
<span class="d-inline-flex mr-2">
<svg width="16" height="16" viewBox="0 0 16 16">
${getIconPath(link)}
</svg>
</span>
${link.name}
</a>
</li>
`
}).join('')
const ariaLabel = [
` ${translate.view}[${links[0].owner}]${translate.allRepos} `,
`${translate.allRepos} : ${sortedLinks.length}`,
stats.privateTrue > 0 ? `${translate.privateRepos} ${stats.privateTrue}` : '',
stats.privateFalse > 0 ? `${translate.publicRepos} ${stats.privateFalse}` : '',
stats.forkTrue > 0 ? `${translate.forkRepos} ${stats.forkTrue}` : ''
].filter(Boolean).join('\n')
const hide = isMobileDevice() ? ' style="display: none' : ''
const detailsHTML = `
<details id="view-global-user-repos" class="details-overlay details-reset position-relative d-flex">
<summary role="button" type="button" class="btn text-center" id="hideSummary"${hide};>
<span class="d-none d-xl-flex flex-items-center tooltipped tooltipped-s" aria-label="${ariaLabel}">
<mark>[${links[0].owner}]</mark>
<span class="dropdown-caret ml-2"></span>
</span>
<span class="d-inline-block d-xl-none">
[${links[0].owner}]
<span class="dropdown-caret d-none d-sm-inline-block d-md-none d-lg-inline-block"></span>
</span>
</summary>
<div>
<ul class="dropdown-menu dropdown-menu-sw">
${listItems}
</ul>
</div>
</details>`
existingButton.insertAdjacentHTML('beforebegin', detailsHTML)
} else {
}
if (isMobileDevice()) {
const svgElement = document.querySelector('.AppHeader-globalBar-start > a')
svgElement.addEventListener('click', function (event) {
event.preventDefault()
const summary = document.getElementById('hideSummary')
summary.click()
})
}
}
async function getUserRepos(href, header = {}) {
try {
const response = await fetch(`${href}`, {
headers: header
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
return await response.json()
} catch (error) {
console.error('Fetch error:', error)
throw error
}
}
async function getUserAllRepos(href, header = {}, getAll = false, maxPage = 0) {
try {
let allRepos = []
let page = 1
const perPage = 100
if (!getAll) {
const url = `${href}?per_page=${perPage}&page=1`//如果不需要获取所有仓库,直接请求第一页数据
const response = await fetch(url, { headers: header })
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
const repos = await response.json()
return repos.length > 0 ? repos : allRepos // 返回第一页数据
}
while (true) {
const url = `${href}?per_page=${perPage}&page=${page}`
const response = await fetch(url, { headers: header })
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
const repos = await response.json()
if (repos.length === 0) break // 如果没有更多数据,退出循环
allRepos = allRepos.concat(repos)
page++ // 增加页数
// 如果设定了最大页数并且已经达到了最大页数,结束循环
if (maxPage !== 0 && page > maxPage) break
}
return allRepos
} catch (error) {
console.error('Fetch error:', error)
throw error
}
}
function fetchReposWithCache(ownerKey, reposApi, headers) {
const localData = localStorage.getItem(ownerKey)
const currentTime = new Date().getTime()
if (localData) {
const parsedData = JSON.parse(localData)
const localTimeStamp = new Date(parsedData.timeStamp).getTime()
if (currentTime - localTimeStamp < timeToSeconds(DELAY) * 1000) {
console.log('本地缓存数据未过期,直接使用本地数据')
insertReposList(parsedData.reposArray, USETIP)
return
}
}
getUserAllRepos(reposApi, headers)
.then(data => {
const reposArray = data.map(repo => ({
name: repo.name,
private: repo.private,
html_url: repo.html_url,
fork: repo.fork,
description: repo.description,
stargazers_count: repo.stargazers_count,
owner: repo.owner.login,
forks_count: repo.forks_count,
open_issues_count: repo.open_issues_count,
language: repo.language,
size: repo.size,
created_at: systemTime(repo.created_at),
updated_at: systemTime(repo.updated_at),
pushed_at: systemTime(repo.pushed_at)
}))
const timeStamp = new Date().toISOString()
const dataToStore = {
reposArray: reposArray,
timeStamp: timeStamp
}
localStorage.setItem(ownerKey, JSON.stringify(dataToStore))
insertReposList(reposArray, USETIP)
})
.catch(error => console.error('Error fetching data:', error))
}
//LINK - 帮助小子程序
function getHumanReadableSize(sizeInKB) {
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
const size = sizeInKB * 1024
let i = parseInt(Math.floor(Math.log(size) / Math.log(1024)))
const humanReadableSize = (size / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i]
return humanReadableSize
}
function systemTime(isoString) {
const date = new Date(isoString)
return date.toLocaleString()
}
function timeToSeconds(timeStr) {
let hours = 0, minutes = 0, seconds = 0
const hoursMatch = timeStr.match(/(\d{1,2})h/)
const minutesMatch = timeStr.match(/(\d{1,2})m/)
const secondsMatch = timeStr.match(/(\d{1,2})s/)
if (hoursMatch) {
hours = parseInt(hoursMatch[1], 10)
}
if (minutesMatch) {
minutes = parseInt(minutesMatch[1], 10)
}
if (secondsMatch) {
seconds = parseInt(secondsMatch[1], 10)
}
let totalSeconds = (hours * 3600) + (minutes * 60) + seconds
return totalSeconds
}
function isMobileDevice() {
return /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}