1.4.3原版
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './friends-rss';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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)]',
|
||||
},
|
||||
}),
|
||||
];
|
||||
Reference in New Issue
Block a user