1.4.3原版

This commit is contained in:
anian
2026-03-15 23:33:02 +08:00
commit 54fb39d15c
135 changed files with 14156 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
{
"root": true,
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"env": {
"browser": true
},
"rules": {
"no-prototype-builtins": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_"
}
]
}
}
+24
View File
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+8
View File
@@ -0,0 +1,8 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"singleQuote": true,
"bracketSpacing": true,
"arrowParens": "always",
"printWidth": 100
}
+59
View File
@@ -0,0 +1,59 @@
{
"name": "@kunkunyu/fridends-rss",
"author": {
"name": "困困鱼",
"url": "https://github.com/chengzhongxue"
},
"maintainers": [
{
"name": "困困鱼",
"url": "https://github.com/chengzhongxue"
}
],
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/friends-rss.js"
},
"./var.css": "./var.css"
},
"main": "./dist/friends-rss.js",
"module": "./dist/friends-rss.js",
"types": "./dist/index.d.ts",
"files": [
"dist",
"var.css"
],
"scripts": {
"dev": "vite --config vite.config.dev.ts",
"build": "vite build --config vite.config.lib.ts",
"lint": "lit-analyzer && eslint 'src/**/*.ts'",
"prettier": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --ignore-path ./.gitignore --write",
"test": "vitest",
"test:ci": "vitest --run"
},
"dependencies": {
"lit": "^3.1.3"
},
"devDependencies": {
"@iconify/json": "^2.2.216",
"@rushstack/eslint-patch": "^1.7.2",
"@types/node": "20",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@unocss/preset-icons": "^0.60.4",
"@unocss/reset": "^0.60.4",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"lit-analyzer": "^2.0.3",
"prettier": "^3.3.0",
"rollup-plugin-copy": "^3.5.0",
"typescript": "^5.4.5",
"unocss": "^0.60.4",
"vite": "^5.2.12",
"vite-plugin-dts": "^3.9.1",
"vitest": "^1.6.0"
}
}
+93
View File
@@ -0,0 +1,93 @@
import resetStyles from '@unocss/reset/tailwind.css?inline';
import { LitElement, css, html, unsafeCSS } from 'lit';
import { property, state } from 'lit/decorators.js';
import { RssDetail } from './types';
import { repeat } from 'lit/directives/repeat.js';
import './loading-bar';
export class FriendsRss extends LitElement {
@property({ type: String })
src = '';
@property({ type: String })
layout: 'list' | 'grid' = 'list';
@state()
rssDetail?: RssDetail;
@state()
loading = false;
override connectedCallback() {
super.connectedCallback();
this.fetchRssDetail();
}
async fetchRssDetail() {
// Mock
try {
this.loading = true;
const response = await fetch(
`/apis/api.friend.moony.la/v1alpha1/parsingrss?rssUrl=${this.src}`
);
if (!response.ok) {
throw new Error('Failed to fetch site data');
}
this.rssDetail = (await response.json()) as RssDetail;
} catch (error) {
console.error(error);
} finally {
this.loading = false;
}
}
override render() {
if (this.loading) {
return html`<loading-bar></loading-bar>`;
}
return html`
<ul class="grid ${this.layout == 'grid' ? 'grid-cols-2' : ''}">
${repeat(
// @ts-ignore
this.rssDetail?.channel.items,
(item) => item.link,
(item) => html`
<li class="sm:flex-row relative p-2 space-y-1 z-[1]">
<a
href=${item?.link}
target="_blank"
>
<h2 class="font-semibold text-base text-title line-clamp-2 lg:line-clamp-1">
${item?.title}
</h2>
</a>
<p class="text-sm text-description line-clamp-2">${item?.description}</p>
</li>
`
)}
</ul>
`;
}
static override styles = [
unsafeCSS(resetStyles),
css`
:host {
display: inline-block;
width: 100%;
}
@unocss-placeholder;
`,
];
}
customElements.get('friends-rss') || customElements.define('friends-rss', FriendsRss);
declare global {
interface HTMLElementTagNameMap {
'friends-rss': FriendsRss;
}
}
+2
View File
@@ -0,0 +1,2 @@
export * from './friends-rss';
+51
View File
@@ -0,0 +1,51 @@
import { LitElement, css, html } from 'lit';
export class LoadingBar extends LitElement {
override render() {
return html`
<svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle
style="opacity: 0.25;"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
></circle>
<path
style="opacity: 0.75;"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
fill="currentColor"
></path>
</svg>
`;
}
static override styles = css`
:host {
display: flex;
align-items: center;
justify-content: center;
padding: 1em;
}
svg {
height: 1.25em;
width: 1.25em;
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
`;
}
customElements.get('loading-bar') || customElements.define('loading-bar', LoadingBar);
declare global {
interface HTMLElementTagNameMap {
'loading-block': LoadingBar;
}
}
+28
View File
@@ -0,0 +1,28 @@
export interface RssDetail {
'channel': Channel;
}
export interface Channel {
'description'?: string;
'items': Array<Item>;
'link': string;
'title': string;
}
export interface Item {
'author'?: string;
'description'?: string;
'link': string;
'pubDate': string;
'title': string;
'uri'?: string;
}
+1
View File
@@ -0,0 +1 @@
/// <reference types="vite/client" />
@@ -0,0 +1,14 @@
import presetIcons from '@unocss/preset-icons';
import { presetUno } from 'unocss';
import UnoCSS from 'unocss/vite';
export const sharedPluginsConfig = [
UnoCSS({
mode: 'shadow-dom',
presets: [presetUno(), presetIcons()],
shortcuts: {
'text-title': 'text-[var(--friends-rss-title-color,#18181b)]',
'text-description': 'text-[var(--friends-rss-description-color,#71717a)]',
},
}),
];
+33
View File
@@ -0,0 +1,33 @@
{
"compilerOptions": {
"target": "es2021",
"module": "es2020",
"lib": ["es2021", "DOM", "DOM.Iterable"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"inlineSources": true,
"outDir": "./types",
"rootDir": "./src",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitThis": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"noImplicitOverride": true,
"skipLibCheck": true,
"plugins": [
{
"name": "ts-lit-plugin",
"strict": true
}
]
},
"include": ["src/**/*.ts"]
}
+16
View File
@@ -0,0 +1,16 @@
@media (prefers-color-scheme: dark) {
.color-scheme-auto,
[data-color-scheme='auto'] friends-rss {
color-scheme: dark;
--friends-rss-title-color: #f4f4f5;
--friends-rss-description-color: #a1a1aa;
}
}
.color-scheme-dark,
.dark,
[data-color-scheme='dark'] friends-rss {
color-scheme: dark;
--friends-rss-title-color: #f4f4f5;
--friends-rss-description-color: #a1a1aa;
}
+14
View File
@@ -0,0 +1,14 @@
import { defineConfig } from 'vite';
import { sharedPluginsConfig } from './src/vite/shared-plugin-config';
export default defineConfig({
plugins: [...sharedPluginsConfig],
server: {
proxy: {
'/apis': {
target: 'http://localhost:8090',
changeOrigin: true,
},
},
},
});
+34
View File
@@ -0,0 +1,34 @@
import copy from 'rollup-plugin-copy';
import { fileURLToPath } from 'url';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import { sharedPluginsConfig } from './src/vite/shared-plugin-config';
export default defineConfig({
build: {
lib: {
entry: 'src/index.ts',
name: 'friends-rss',
fileName: 'friends-rss',
formats: ['iife', 'es'],
},
emptyOutDir: true,
rollupOptions: {
output: {
extend: true,
},
},
},
plugins: [
...sharedPluginsConfig,
dts(),
copy({
targets: [
{
src: ['./dist/friends-rss.iife.js', './var.css'],
dest: fileURLToPath(new URL('../../src/main/resources/static', import.meta.url)),
},
],
}),
],
});
+7
View File
@@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
include: ['src/**/*.test.ts'],
},
});