Greasy Fork

来自缓存

Greasy Fork is available in English.

新闻速递

Fetch news from API and open in a new tab with responsive design and translation.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        新闻速递
// @namespace   Violentmonkey Scripts
// @match       *://*/*
// @grant       GM_xmlhttpRequest
// @grant       GM_openInTab
// @grant       GM_registerMenuCommand
// @version     1.5
// @description Fetch news from API and open in a new tab with responsive design and translation.
// @run-at      document-end
// ==/UserScript==

(function() {
  'use strict';

  const apiKey = 'dac6abc0634b4de08429b2580628dba8';
  const apiUrl = `https://newsapi.org/v2/top-headlines?country=us&apiKey=${apiKey}`;

  // Function to fetch and display news
  function fetchAndDisplayNews() {
    GM_xmlhttpRequest({
      method: "GET",
      url: apiUrl,
      onload: function(response) {
        if (response.status === 200) {
          const data = JSON.parse(response.responseText);
          if (data.articles && data.articles.length > 0) {
            let newsContent = `
              <!DOCTYPE html>
              <html lang="zh-CN">
              <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>新闻列表</title>
                <style>
                  body { font-family: sans-serif; margin: 20px; }
                  h1 { text-align: center; }
                  ul { list-style: none; padding: 0; }
                  li { border: 1px solid #eee; padding: 15px; margin-bottom: 10px; border-radius: 5px; }
                  a { text-decoration: none; font-weight: bold; color: #333; }
                  p { color: #666; margin-top: 5px; }
                  a:hover { color: #0056b3; }
                  .translation { font-style: italic; color: #888; margin-top: 5px; }
                   @media (max-width: 600px) {
                      body { margin: 10px; }
                      li { padding: 10px; }
                      h1 {font-size: 1.5em;}
                  }
                </style>
              </head>
              <body>
              <h1>Latest News</h1>
              <ul>
            `;

            const translatePromises = data.articles.map(async (article) => {
                const translatedTitle = await translateText(article.title, 'en', 'zh-CN');
                const translatedDescription = article.description ? await translateText(article.description, 'en', 'zh-CN') : 'No translation available.';
                return { ...article, translatedTitle, translatedDescription };
            });

            Promise.all(translatePromises).then((translatedArticles) => {
              translatedArticles.forEach(article => {
                newsContent += `
                  <li>
                    <a href="${article.url}" target="_blank">${article.title}</a>
                      <p class="translation" style="color: green;">${article.translatedTitle}</p>
                    <p>${article.description || 'No description available.'}</p>
                     <p class="translation" style="color: green;">${article.translatedDescription}</p>
                  </li>
                `;
              });

              newsContent += `
                </ul>
                </body>
                </html>
              `;
              GM_openInTab(`data:text/html;charset=utf-8,${encodeURIComponent(newsContent)}`, { active: true });
            });

          } else {
            alert('No news found.');
          }
        } else {
          alert('Failed to fetch news. Status: ' + response.status);
        }
      },
      onerror: function(error) {
        console.error("Error fetching news:", error);
        alert('An error occurred while fetching news.');
      }
    });
  }

  async function translateText(text, sourceLang, targetLang) {
    if (!text) {
      return '';
    }
    const encodedText = encodeURIComponent(text);
    const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sourceLang}&tl=${targetLang}&dt=t&q=${encodedText}`;

    try {
      const response = await fetch(url);
      if (!response.ok) {
        console.error("Translation API failed:", response.status);
        return 'Translation failed.';
      }
      const data = await response.json();
      return data[0][0][0];
    } catch (error) {
      console.error("Error during translation:", error);
      return 'Translation failed.';
    }
  }

  // Register the menu command
  GM_registerMenuCommand("Fetch Latest News", fetchAndDisplayNews);

})();