4.8 KiB
Contributing to NewsNow
Thank you for considering contributing to NewsNow! This document provides guidelines and instructions for contributing to the project.
Adding a New Source
NewsNow is built to be easily extensible with new sources. Here's a step-by-step guide on how to add a new source:
1. Create a Feature Branch
Always create a feature branch for your changes:
git checkout -b feature-name
For example, to add a Bilibili hot video source:
git checkout -b bilibili-hot-video
2. Register the Source in Configuration
Add your new source to the source configuration in /shared/pre-sources.ts:
"bilibili": {
name: "哔哩哔哩",
color: "blue",
home: "https://www.bilibili.com",
sub: {
"hot-search": {
title: "热搜",
column: "china",
type: "hottest"
},
"hot-video": { // Add your new sub-source here
title: "热门视频",
column: "china",
type: "hottest"
}
}
};
For a completely new source, add a new top-level entry:
"newsource": {
name: "New Source",
color: "blue",
home: "https://www.example.com",
column: "tech", // Pick an appropriate column
type: "hottest" // Or "realtime" if it's a news feed
};
3. Implement the Source Fetcher
Create or modify a file in the /server/sources/ directory. If your source is related to an existing one (like adding a new Bilibili sub-source), modify the existing file:
// In /server/sources/bilibili.ts
// Define interface for API response
interface HotVideoRes {
code: number;
message: string;
ttl: number;
data: {
list: {
aid: number;
// ... other fields
bvid: string;
title: string;
pubdate: number;
desc: string;
pic: string;
owner: {
mid: number;
name: string;
face: string;
};
stat: {
view: number;
like: number;
reply: number;
// ... other stats
};
}[];
};
}
// Define source getter function
const hotVideo = defineSource(async () => {
const url = "https://api.bilibili.com/x/web-interface/popular";
const res: HotVideoRes = await myFetch(url);
return res.data.list.map((video) => ({
id: video.bvid,
title: video.title,
url: `https://www.bilibili.com/video/${video.bvid}`,
pubDate: video.pubdate * 1000,
extra: {
info: `${video.owner.name} · ${formatNumber(video.stat.view)}观看 · ${formatNumber(video.stat.like)}点赞`,
hover: video.desc,
icon: proxyPicture(video.pic),
},
}));
});
// Helper function for formatting numbers
function formatNumber(num: number): string {
if (num >= 10000) {
return `${Math.floor(num / 10000)}w+`;
}
return num.toString();
}
// Export the source
export default defineSource({
bilibili: hotSearch,
"bilibili-hot-search": hotSearch,
"bilibili-hot-video": hotVideo, // Add your new source here
});
For completely new sources, create a new file in /server/sources/ named after your source (e.g., newsource.ts).
4. Regenerate Source Files
After adding or modifying source files, run the following command to regenerate the necessary files:
npm run presource
This will update the sources.json file and any other necessary configuration.
5. Test Your Changes
Start the development server to test your changes:
npm run dev
Access the application in your browser and ensure that your new source is appearing and working correctly.
6. Commit Your Changes
Once everything is working, commit your changes:
git add .
git commit -m "Add new source: source-name"
7. Create a Pull Request
Push your changes to your fork and create a pull request against the main repository:
git push origin feature-name
Source Structure
NewsItem Structure
Each source should return an array of objects that conform to the NewsItem interface:
interface NewsItem {
id: string | number; // Unique identifier for the item
title: string; // Title of the news item
url: string; // URL to the full content
mobileUrl?: string; // Optional mobile-specific URL
pubDate?: number | string; // Publication date
extra?: {
hover?: string; // Text to display on hover
date?: number | string; // Formatted date
info?: false | string; // Additional information
diff?: number; // Time difference
icon?:
| false
| string
| {
// Icon for the item
url: string;
scale: number;
};
};
}
Code Style
Please follow the existing code style in the project. The project uses TypeScript and follows modern ES6+ conventions.
License
By contributing to this project, you agree that your contributions will be licensed under the project's license.