Fix audible provider & add more YT channel (#618)
* add more youtube channel * fix audible provider * fix youtube video card style
This commit is contained in:
@@ -16,20 +16,18 @@ export class AudibleProvider {
|
||||
return new Promise<string>((resolve, _reject) => {
|
||||
const view = new WebContentsView();
|
||||
view.webContents.loadURL(this.baseURL + path);
|
||||
view.webContents.on("did-finish-load", () => {
|
||||
logger.debug(`Scraped ${this.baseURL + path}`);
|
||||
view.webContents.on("did-stop-loading", () => {
|
||||
logger.debug(`Finish loading ${this.baseURL + path}`);
|
||||
view.webContents
|
||||
.executeJavaScript(`document.documentElement.innerHTML`)
|
||||
.then((html) => {
|
||||
resolve(html as string);
|
||||
})
|
||||
.catch((err) => {
|
||||
resolve("");
|
||||
})
|
||||
.finally(() => view.webContents.close());
|
||||
});
|
||||
view.webContents.on("did-fail-load", () => {
|
||||
logger.warn(`Failed to scrape ${this.baseURL + path}`);
|
||||
view.webContents.close();
|
||||
resolve("");
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -11,23 +11,19 @@ export class TedProvider {
|
||||
view.webContents.loadURL(url);
|
||||
logger.debug("started scraping", url);
|
||||
|
||||
view.webContents.on("did-finish-load", () => {
|
||||
logger.debug("finished scraping", url);
|
||||
view.webContents.on("did-stop-loading", () => {
|
||||
logger.debug("finished loading", url);
|
||||
view.webContents
|
||||
.executeJavaScript(`document.documentElement.innerHTML`)
|
||||
.then((html) => resolve(html as string))
|
||||
.catch((error) => {
|
||||
logger.warn("Failed to scrape", url, error);
|
||||
resolve("");
|
||||
})
|
||||
.finally(() => {
|
||||
view.webContents.close();
|
||||
});
|
||||
});
|
||||
view.webContents.on(
|
||||
"did-fail-load",
|
||||
(_event, _errorCode, error, validatedURL) => {
|
||||
logger.warn("Failed to scrape", url, error, validatedURL);
|
||||
view.webContents.close();
|
||||
resolve("");
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -11,11 +11,15 @@ export class YoutubeProvider {
|
||||
view.webContents.loadURL(url);
|
||||
logger.debug("started scraping", url);
|
||||
|
||||
view.webContents.on("did-finish-load", () => {
|
||||
logger.debug("finished scraping", url);
|
||||
view.webContents.on("did-stop-loading", () => {
|
||||
logger.debug("finished loading", url);
|
||||
view.webContents
|
||||
.executeJavaScript(`document.documentElement.innerHTML`)
|
||||
.then((html) => resolve(html as string))
|
||||
.catch((error) => {
|
||||
logger.warn("Failed to scrape", url, error);
|
||||
resolve("");
|
||||
})
|
||||
.finally(() => {
|
||||
view.webContents.close();
|
||||
});
|
||||
@@ -45,12 +49,13 @@ export class YoutubeProvider {
|
||||
const videoList = videoContents
|
||||
.filter((i: any) => i.richItemRenderer)
|
||||
.map((video: any) => {
|
||||
const thumbnails =
|
||||
video.richItemRenderer.content.videoRenderer.thumbnail.thumbnails;
|
||||
|
||||
return {
|
||||
title:
|
||||
video.richItemRenderer.content.videoRenderer.title.runs[0].text,
|
||||
thumbnail:
|
||||
video.richItemRenderer.content.videoRenderer.thumbnail
|
||||
.thumbnails[0].url,
|
||||
thumbnail: thumbnails[thumbnails.length - 1].url,
|
||||
videoId: video.richItemRenderer.content.videoRenderer.videoId,
|
||||
duration:
|
||||
video.richItemRenderer.content.videoRenderer.lengthText
|
||||
@@ -65,18 +70,21 @@ export class YoutubeProvider {
|
||||
}
|
||||
};
|
||||
|
||||
videos = async () => {
|
||||
const html = await this.scrape("https://www.youtube.com/@CNN/videos");
|
||||
videos = async (channel: string) => {
|
||||
const html = await this.scrape(`https://www.youtube.com/${channel}/videos`);
|
||||
return this.extractVideos(html);
|
||||
};
|
||||
|
||||
registerIpcHandlers = () => {
|
||||
ipcMain.handle("youtube-provider-videos", async () => {
|
||||
try {
|
||||
return await this.videos();
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
ipcMain.handle(
|
||||
"youtube-provider-videos",
|
||||
async (_event, channel: string) => {
|
||||
try {
|
||||
return await this.videos(channel);
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,8 +85,8 @@ contextBridge.exposeInMainWorld("__ENJOY_APP__", {
|
||||
},
|
||||
},
|
||||
youtube: {
|
||||
videos: () => {
|
||||
return ipcRenderer.invoke("youtube-provider-videos");
|
||||
videos: (channel: string) => {
|
||||
return ipcRenderer.invoke("youtube-provider-videos", channel);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { LoaderIcon } from "lucide-react";
|
||||
|
||||
export const YoutubeVideosSegment = () => {
|
||||
export const YoutubeVideosSegment = (props: { channel: string }) => {
|
||||
const { channel } = props;
|
||||
const navigate = useNavigate();
|
||||
const { EnjoyApp } = useContext(AppSettingsProviderContext);
|
||||
const [videos, setvideos] = useState<YoutubeVideoType[]>([]);
|
||||
@@ -46,18 +47,20 @@ export const YoutubeVideosSegment = () => {
|
||||
};
|
||||
|
||||
const fetchYoutubeVideos = async () => {
|
||||
const cachedVideos = await EnjoyApp.cacheObjects.get("youtube-videos");
|
||||
const cachedVideos = await EnjoyApp.cacheObjects.get(
|
||||
`youtube-videos-${channel}`
|
||||
);
|
||||
if (cachedVideos) {
|
||||
setvideos(cachedVideos);
|
||||
return;
|
||||
}
|
||||
|
||||
EnjoyApp.providers.youtube
|
||||
.videos()
|
||||
.videos(channel)
|
||||
.then((videos) => {
|
||||
if (!videos) return;
|
||||
|
||||
EnjoyApp.cacheObjects.set("youtube-videos", videos, 60 * 10);
|
||||
EnjoyApp.cacheObjects.set(`youtube-videos-${channel}`, videos, 60 * 10);
|
||||
setvideos(videos);
|
||||
})
|
||||
.catch((err) => {
|
||||
@@ -90,7 +93,7 @@ export const YoutubeVideosSegment = () => {
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="space-y-1">
|
||||
<h2 className="text-2xl font-semibold tracking-tight capitalize">
|
||||
{t("from")} Youtube CNN
|
||||
{t("from")} Youtube {channel}
|
||||
</h2>
|
||||
</div>
|
||||
<div className="ml-auto mr-4"></div>
|
||||
@@ -183,18 +186,18 @@ const YoutubeVideoCard = (props: {
|
||||
|
||||
return (
|
||||
<div onClick={onClick} className="w-64 cursor-pointer">
|
||||
<div className="aspect-[4/2.5] border rounded-lg overflow-hidden relative">
|
||||
<div className="aspect-[16/9] border rounded-lg overflow-hidden relative mb-4">
|
||||
<img
|
||||
src={video.thumbnail}
|
||||
alt={video.title}
|
||||
className="hover:scale-105 object-cover w-screen"
|
||||
className="hover:scale-105 object-cover w-full h-full"
|
||||
/>
|
||||
|
||||
<div className="absolute bottom-0 left-0 right-0 p-2 bg-black bg-opacity-50">
|
||||
<div className="text-xs text-white text-right">{video.duration}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm font-semibold mt-4 max-w-full h-5 mb-10">
|
||||
<div className="text-sm font-semibold h-10 max-w-full line-clamp-2">
|
||||
{video.title}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,9 +2,7 @@ import {
|
||||
AudiosSegment,
|
||||
AudibleBooksSegment,
|
||||
StoriesSegment,
|
||||
TedIdeasSegment,
|
||||
VideosSegment,
|
||||
TedTalksSegment,
|
||||
YoutubeVideosSegment,
|
||||
} from "@renderer/components";
|
||||
|
||||
@@ -16,9 +14,9 @@ export default () => {
|
||||
<VideosSegment />
|
||||
<StoriesSegment />
|
||||
<AudibleBooksSegment />
|
||||
<TedTalksSegment />
|
||||
<TedIdeasSegment />
|
||||
<YoutubeVideosSegment />
|
||||
<YoutubeVideosSegment channel="@TED" />
|
||||
<YoutubeVideosSegment channel="@CNN" />
|
||||
<YoutubeVideosSegment channel="@nytimes" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
2
enjoy/src/types/enjoy-app.d.ts
vendored
2
enjoy/src/types/enjoy-app.d.ts
vendored
@@ -42,7 +42,7 @@ type EnjoyAppType = {
|
||||
downloadTalk: (url: string) => Promise<{ audio: string; video: string }>;
|
||||
};
|
||||
youtube: {
|
||||
videos: () => Promise<YoutubeVideoType[]>;
|
||||
videos: (channel: string) => Promise<YoutubeVideoType[]>;
|
||||
};
|
||||
};
|
||||
view: {
|
||||
|
||||
Reference in New Issue
Block a user