From 6d2e56fdb840a9d132951dba4f0345edae0b1e71 Mon Sep 17 00:00:00 2001 From: zhanglun Date: Fri, 29 Dec 2023 21:27:03 +0800 Subject: [PATCH] refactor: make /api/articles more simpler --- src-tauri/src/feed/article.rs | 157 ++++++----------------- src-tauri/src/server/handlers/article.rs | 40 +----- src-tauri/src/server/handlers/common.rs | 1 - src/App.tsx | 1 - src/helpers/dataAgent.ts | 16 --- src/index.tsx | 1 - src/layout/Article/Layout1.tsx | 11 +- src/layout/Article/index.tsx | 4 +- src/layout/Article/useArticle.ts | 28 ++-- 9 files changed, 67 insertions(+), 192 deletions(-) diff --git a/src-tauri/src/feed/article.rs b/src-tauri/src/feed/article.rs index ca11bc303..0ccadd369 100644 --- a/src-tauri/src/feed/article.rs +++ b/src-tauri/src/feed/article.rs @@ -1,8 +1,8 @@ -use chrono::{Utc, Duration}; +use crate::core::config::get_user_config; +use chrono::{Duration, Utc}; use diesel::prelude::*; use diesel::sql_types::*; use serde::{Deserialize, Serialize}; -use crate::core::config::get_user_config; use crate::db::establish_connection; use crate::models; @@ -19,7 +19,9 @@ pub enum ArticleReadStatus { #[derive(Debug, Serialize, Deserialize)] pub struct ArticleFilter { pub feed_uuid: Option, + pub folder_uuid: Option, pub item_type: Option, + pub is_today: Option, pub read_status: Option, pub cursor: Option, pub limit: Option, @@ -84,14 +86,14 @@ impl Article { if let Some(item_type) = filter.item_type { if item_type == String::from("folder") { relations = schema::feed_metas::dsl::feed_metas - .filter(schema::feed_metas::folder_uuid.eq(&channel_uuid)) - .load::(&mut connection) - .expect("Expect find channel"); - } else { + .filter(schema::feed_metas::folder_uuid.eq(&channel_uuid)) + .load::(&mut connection) + .expect("Expect find channel"); + } else { relations = schema::feed_metas::dsl::feed_metas - .filter(schema::feed_metas::uuid.eq(&channel_uuid)) - .load::(&mut connection) - .expect("Expect find channel"); + .filter(schema::feed_metas::uuid.eq(&channel_uuid)) + .load::(&mut connection) + .expect("Expect find channel"); } } @@ -136,48 +138,9 @@ impl Article { for uuid in channel_uuids { query = query.bind::(uuid); } - } - - match filter.read_status { - Some(0) => { - 1; - } - Some(status) => { - query = query - .sql(" AND A.read_status = ?") - .bind::(status); - } - None => { - 1; - } - } - - query = query.sql(" ORDER BY A.pub_date DESC "); - - if let Some(l) = filter.limit { - query = query.sql(" limit ?").bind::(l); - limit = l; - } - - if let Some(c) = filter.cursor { - query = query.sql(" OFFSET ?").bind::((c - 1) * limit); - } - - let result = query - .load::(&mut connection) - .expect("Expect loading articles"); - - ArticleQueryResult { list: result } - } - - /// get today articles for Today collection - pub fn get_today_articles(filter: ArticleFilter) -> ArticleQueryResult { - let mut connection = establish_connection(); - let mut query = diesel::sql_query("").into_boxed(); - let mut limit = 12; - - query = query.sql( - " + } else if let Some(_is_today) = filter.is_today { + query = query.sql( + " SELECT A.id, A.uuid, A.feed_uuid, @@ -196,67 +159,30 @@ impl Article { articles as A ON C.uuid = A.feed_uuid WHERE DATE(A.create_date) = DATE('now')", - ); - - match filter.read_status { - Some(0) => { - 1; - } - Some(status) => { - query = query - .sql(" AND A.read_status = ?") - .bind::(status); - } - None => { - 1; - } - } - - query = query.sql(" ORDER BY A.pub_date DESC "); - - if let Some(l) = filter.limit { - query = query.sql(" limit ?").bind::(l); - limit = l; - } - - if let Some(c) = filter.cursor { - query = query.sql(" OFFSET ?").bind::((c - 1) * limit); + ); + } else { + query = query.sql( + " + SELECT + A.id, A.uuid, + A.feed_uuid, + C.title as feed_title, + C.link as feed_url, + A.link, + A.title, + A.feed_url, + A.description as description, + A.pub_date, + A.create_date, + A.read_status + FROM + feeds as C + LEFT JOIN + articles as A + ON C.uuid = A.feed_uuid ", + ); } - let result = query - .load::(&mut connection) - .expect("Expect loading articles"); - - ArticleQueryResult { list: result } - } - - /// get all articles for All Items collection - pub fn get_all_articles(filter: ArticleFilter) -> ArticleQueryResult { - let mut connection = establish_connection(); - let mut query = diesel::sql_query("").into_boxed(); - let mut limit = 12; - - query = query.sql( - " - SELECT - A.id, A.uuid, - A.feed_uuid, - C.title as feed_title, - C.link as feed_url, - A.link, - A.title, - A.feed_url, - A.description as description, - A.pub_date, - A.create_date, - A.read_status - FROM - feeds as C - LEFT JOIN - articles as A - ON C.uuid = A.feed_uuid ", - ); - match filter.read_status { Some(0) => { 1; @@ -324,7 +250,7 @@ impl Article { result.pop() } else { None - } + }; } pub fn mark_as_read(params: MarkAllUnreadParam) -> usize { @@ -449,7 +375,7 @@ impl Article { pub fn purge_articles() -> usize { let user_config = get_user_config(); - if let Some(cfg) = user_config { + if let Some(cfg) = user_config { if cfg.purge_on_days == 0 { return 0; } @@ -462,12 +388,9 @@ impl Article { query = query.filter(schema::articles::read_status.eq(2)); } - let query = query - .filter(schema::articles::create_date.lt(expired_date)); + let query = query.filter(schema::articles::create_date.lt(expired_date)); - let result = query - .execute(&mut connection) - .expect("purge failed!"); + let result = query.execute(&mut connection).expect("purge failed!"); log::info!("{:?} articles purged", result); diff --git a/src-tauri/src/server/handlers/article.rs b/src-tauri/src/server/handlers/article.rs index 032b968f9..0203c2a32 100644 --- a/src-tauri/src/server/handlers/article.rs +++ b/src-tauri/src/server/handlers/article.rs @@ -1,4 +1,4 @@ -use actix_web::{get, post, put, web, Responder, Result}; +use actix_web::{get, post, web, Responder, Result}; use serde::{Deserialize, Serialize}; use crate::core; @@ -89,7 +89,9 @@ pub async fn handle_articles( ) -> Result { let filter = feed::article::ArticleFilter { feed_uuid: query.feed_uuid.clone(), + folder_uuid: query.folder_uuid.clone(), item_type: query.item_type.clone(), + is_today: query.is_today.clone(), read_status: query.read_status.clone(), cursor: query.cursor.clone(), limit: query.limit.clone(), @@ -100,40 +102,6 @@ pub async fn handle_articles( Ok(web::Json(res)) } -#[get("/api/all-articles")] -pub async fn handle_get_all_articles( - query: web::Query, -) -> Result { - let filter = feed::article::ArticleFilter { - feed_uuid: query.feed_uuid.clone(), - item_type: query.item_type.clone(), - read_status: query.read_status.clone(), - cursor: query.cursor.clone(), - limit: query.limit.clone(), - }; - - let res = feed::article::Article::get_all_articles(filter); - - Ok(web::Json(res)) -} - -#[get("/api/today-articles")] -pub async fn handle_get_today_articles( - query: web::Query, -) -> Result { - let filter = feed::article::ArticleFilter { - feed_uuid: query.feed_uuid.clone(), - item_type: query.item_type.clone(), - read_status: query.read_status.clone(), - cursor: query.cursor.clone(), - limit: query.limit.clone(), - }; - - let res = feed::article::Article::get_today_articles(filter); - - Ok(web::Json(res)) -} - pub fn config(cfg: &mut web::ServiceConfig) { cfg .service(handle_get_article_best_image) @@ -144,7 +112,5 @@ pub fn config(cfg: &mut web::ServiceConfig) { .service(handle_mark_as_read) .service(handle_update_article_read_status) .service(handle_articles) - .service(handle_get_all_articles) - .service(handle_get_today_articles) ; } diff --git a/src-tauri/src/server/handlers/common.rs b/src-tauri/src/server/handlers/common.rs index f008263a1..3627da1bf 100644 --- a/src-tauri/src/server/handlers/common.rs +++ b/src-tauri/src/server/handlers/common.rs @@ -1,5 +1,4 @@ use actix_web::{get, post, web, Responder, Result}; -use log::kv::ToValue; use serde::{Deserialize, Serialize}; use crate::core::common; diff --git a/src/App.tsx b/src/App.tsx index cebcb93d4..b5f238482 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,6 @@ import { appWindow } from "@tauri-apps/api/window"; import { emit, listen } from "@tauri-apps/api/event"; import { useBearStore } from "@/stores"; -import * as dataAgent from "./helpers/dataAgent"; import { RouteConfig } from "./config"; import { CommandPanel } from "./command"; diff --git a/src/helpers/dataAgent.ts b/src/helpers/dataAgent.ts index 1522b720e..9a79205ea 100644 --- a/src/helpers/dataAgent.ts +++ b/src/helpers/dataAgent.ts @@ -87,22 +87,6 @@ export const getArticleList = async ( return req; }; -export const getTodayArticleList = async (filter: any) => { - return request.get('/today-articles', { - params: { - ...filter - } - }); -}; - -export const getAllArticleList = async (filter: any) => { - return request.get('/all-articles', { - params: { - ...filter - } - }) -}; - export const fetchFeed = async (url: string): Promise<[any, string]> => { return invoke("fetch_feed", { url }); }; diff --git a/src/index.tsx b/src/index.tsx index 2dd307dee..c6f165483 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -16,7 +16,6 @@ import { ArticleContainer } from "./layout/Article"; import { SearchPage } from "./layout/Search"; import { LocalPage } from "./layout/Local"; import { SettingPage } from "./layout/Setting"; - import "./index.css"; const router = createBrowserRouter([ diff --git a/src/layout/Article/Layout1.tsx b/src/layout/Article/Layout1.tsx index ff66ac53d..bdd96af06 100644 --- a/src/layout/Article/Layout1.tsx +++ b/src/layout/Article/Layout1.tsx @@ -1,8 +1,7 @@ import React, { useEffect, useRef, useState } from "react"; -import { useLocation, useParams } from "react-router-dom"; +import { useParams } from "react-router-dom"; import { ArticleList } from "@/components/ArticleList"; import { useBearStore } from "@/stores"; -import { useQuery } from "@/helpers/parseXML"; import { Filter, CheckCheck, RefreshCw } from "lucide-react"; import { @@ -20,10 +19,11 @@ import { useArticle } from "./useArticle"; import { loadFeed } from "@/hooks/useLoadFeed"; export const Layout1 = React.memo( - (props: { feedUuid: string; type: string }) => { + (props: { feedUuid?: string; type?: string }) => { const { feedUuid, type } = props; // @ts-ignore const params: { name: string } = useParams(); + const store = useBearStore((state) => ({ viewMeta: state.viewMeta, article: state.article, @@ -53,7 +53,8 @@ export const Layout1 = React.memo( } }; - const markAllRead = () => {}; + const markAllRead = () => { + }; const changeFilter = (id: any) => { if (store.filterList.some((_) => _.id === parseInt(id, 10))) { @@ -64,7 +65,7 @@ export const Layout1 = React.memo( }; return ( -
+
{ - const [feedUrl, type, feedUuid] = useQuery(); + const [, type, feedUuid] = useQuery(); const store = useBearStore((state) => ({ article: state.article, setArticle: state.setArticle, @@ -26,7 +26,7 @@ export const ArticleContainer = (): JSX.Element => { return (
- + ({ currentFilter: state.currentFilter, })); - const query = { + const query = omit({ read_status: store.currentFilter.id, limit: PAGE_SIZE, feed_uuid: feedUuid, item_type: type, - }; + is_today: isToday && 1, + is_all: isAll && 1, + }); const getKey = (pageIndex: number, previousPageData: any) => { - console.log("%c Line:50 πŸ₯ƒ previousPageData", "color:#42b983", previousPageData); const list = !previousPageData ? [] : previousPageData.list; if (previousPageData && !previousPageData.list?.length) return null; // ε·²η»εˆ°ζœ€εŽδΈ€ι‘΅ return { ...query, - cursor: pageIndex+1, + cursor: pageIndex + 1, }; // SWR key }; const { data, error, isLoading, isValidating, mutate, size, setSize } = useSWRInfinite(getKey, (q) => - request .get("/articles", { params: { ...q }, @@ -42,14 +47,13 @@ export function useArticle (props: UseArticleProps) { .then((res) => res.data) ); - const list = data ? data.reduce((acu, cur) => acu.concat(cur.list || []), []) : []; - console.log("%c Line:74 πŸ₯” data", "color:#2eafb0", data); - console.log("%c Line:74 πŸ₯€ list", "color:#42b983", list); + const list = data + ? data.reduce((acu, cur) => acu.concat(cur.list || []), []) + : []; const articles = list ? [].concat(list) : []; const isLoadingMore = isLoading || (size > 0 && data && typeof data[size - 1] === "undefined"); const isEmpty = !isLoading && list.length === 0; - console.log("%c Line:72 🍧 isEmpty", "color:#f5ce50", isEmpty); const isReachingEnd = isEmpty || (data && data[data.length - 1]?.list?.length < PAGE_SIZE); const isRefreshing = isValidating && data && data.length === size; @@ -65,5 +69,5 @@ export function useArticle (props: UseArticleProps) { isEmpty, isReachingEnd, isRefreshing, - } + }; }