{domain.domain}
diff --git a/pages/api/settings.ts b/pages/api/settings.ts
index 90db4cc..9b5e5a6 100644
--- a/pages/api/settings.ts
+++ b/pages/api/settings.ts
@@ -55,6 +55,7 @@ const updateSettings = async (req: NextApiRequest, res: NextApiResponse
=> {
+ const screenshotAPIKey = process.env.SCREENSHOT_API || '69408-serpbear';
try {
const settingsRaw = await readFile(`${process.cwd()}/data/settings.json`, { encoding: 'utf-8' });
const failedQueueRaw = await readFile(`${process.cwd()}/data/failed_queue.json`, { encoding: 'utf-8' });
@@ -73,6 +74,7 @@ export const getAppSettings = async () : Promise => {
search_console_integrated: !!(process.env.SEARCH_CONSOLE_PRIVATE_KEY && process.env.SEARCH_CONSOLE_CLIENT_EMAIL),
available_scapers: allScrapers.map((scraper) => ({ label: scraper.name, value: scraper.id })),
failed_queue: failedQueue,
+ screenshot_key: screenshotAPIKey,
};
} catch (error) {
console.log('Error Decrypting Settings API Keys!');
@@ -81,7 +83,7 @@ export const getAppSettings = async () : Promise => {
return decryptedSettings;
} catch (error) {
console.log('[ERROR] Getting App Settings. ', error);
- const settings = {
+ const settings: SettingsType = {
scraper_type: 'none',
notification_interval: 'never',
notification_email: '',
@@ -91,6 +93,7 @@ export const getAppSettings = async () : Promise => {
smtp_username: '',
smtp_password: '',
scrape_retry: false,
+ screenshot_key: screenshotAPIKey,
};
const otherSettings = {
available_scapers: allScrapers.map((scraper) => ({ label: scraper.name, value: scraper.id })),
diff --git a/pages/domains/index.tsx b/pages/domains/index.tsx
index f9e2b44..2d1e29c 100644
--- a/pages/domains/index.tsx
+++ b/pages/domains/index.tsx
@@ -3,11 +3,12 @@ import type { NextPage } from 'next';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { CSSTransition } from 'react-transition-group';
+import toast, { Toaster } from 'react-hot-toast';
import TopBar from '../../components/common/TopBar';
import AddDomain from '../../components/domains/AddDomain';
import Settings from '../../components/settings/Settings';
import { useFetchSettings } from '../../services/settings';
-import { useFetchDomains } from '../../services/domains';
+import { fetchDomainScreenshot, useFetchDomains } from '../../services/domains';
import DomainItem from '../../components/domains/DomainItem';
import Icon from '../../components/common/Icon';
@@ -23,32 +24,17 @@ const SingleDomain: NextPage = () => {
const { data: domainsData, isLoading } = useFetchDomains(router, true);
useEffect(() => {
- // console.log('Domains Data: ', domainsData);
- if (domainsData?.domains && domainsData.domains.length > 0) {
- const domainThumbsRaw = localStorage.getItem('domainThumbs');
- const domThumbs = domainThumbsRaw ? JSON.parse(domainThumbsRaw) : {};
+ if (domainsData?.domains && domainsData.domains.length > 0 && appSettings?.settings?.screenshot_key) {
domainsData.domains.forEach(async (domain:DomainType) => {
if (domain.domain) {
- if (!domThumbs[domain.domain]) {
- const domainImageBlob = await fetch(`https://image.thum.io/get/auth/66909-serpbear/maxAge/96/width/200/https://${domain.domain}`).then((res) => res.blob());
- if (domainImageBlob) {
- const reader = new FileReader();
- await new Promise((resolve, reject) => {
- reader.onload = resolve;
- reader.onerror = reject;
- reader.readAsDataURL(domainImageBlob);
- });
- const imageBase: string = reader.result && typeof reader.result === 'string' ? reader.result : '';
- localStorage.setItem('domainThumbs', JSON.stringify({ ...domThumbs, [domain.domain]: imageBase }));
- setDomainThumbs((currentThumbs) => ({ ...currentThumbs, [domain.domain]: imageBase }));
- }
- } else {
- setDomainThumbs((currentThumbs) => ({ ...currentThumbs, [domain.domain]: domThumbs[domain.domain] }));
+ const domainThumb = await fetchDomainScreenshot(domain.domain, appSettings.settings.screenshot_key);
+ if (domainThumb) {
+ setDomainThumbs((currentThumbs) => ({ ...currentThumbs, [domain.domain]: domainThumb }));
}
}
});
}
- }, [domainsData]);
+ }, [domainsData, appSettings]);
useEffect(() => {
// console.log('appSettings.settings: ', appSettings && appSettings.settings);
@@ -57,6 +43,18 @@ const SingleDomain: NextPage = () => {
}
}, [appSettings]);
+ const manuallyUpdateThumb = async (domain: string) => {
+ if (domain && appSettings?.settings?.screenshot_key) {
+ const domainThumb = await fetchDomainScreenshot(domain, appSettings.settings.screenshot_key, true);
+ if (domainThumb) {
+ toast(`${domain} Screenshot Updated Successfully!`, { icon: '✔️' });
+ setDomainThumbs((currentThumbs) => ({ ...currentThumbs, [domain]: domainThumb }));
+ } else {
+ toast(`Failed to Fetch ${domain} Screenshot!`, { icon: '⚠️' });
+ }
+ }
+ };
+
return (
{noScrapprtError && (
@@ -90,6 +88,7 @@ const SingleDomain: NextPage = () => {
selected={false}
isConsoleIntegrated={!!(appSettings && appSettings?.settings?.search_console_integrated) }
thumb={domainThumbs[domain.domain]}
+ updateThumb={manuallyUpdateThumb}
// isConsoleIntegrated={false}
/>;
})}
@@ -115,6 +114,7 @@ const SingleDomain: NextPage = () => {
+
);
};
diff --git a/services/domains.tsx b/services/domains.tsx
index a722ee3..4e73a51 100644
--- a/services/domains.tsx
+++ b/services/domains.tsx
@@ -19,6 +19,36 @@ export async function fetchDomains(router: NextRouter, withStats:boolean) {
return res.json();
}
+export async function fetchDomainScreenshot(domain: string, screenshot_key:string, forceFetch = false): Promise {
+ const domainThumbsRaw = localStorage.getItem('domainThumbs');
+ const domThumbs = domainThumbsRaw ? JSON.parse(domainThumbsRaw) : {};
+ if (!domThumbs[domain] || forceFetch) {
+ try {
+ const screenshotURL = `https://image.thum.io/get/auth/${screenshot_key}/maxAge/96/width/200/https://${domain}`;
+ const domainImageRes = await fetch(screenshotURL);
+ const domainImageBlob = domainImageRes.status === 200 ? await domainImageRes.blob() : false;
+ if (domainImageBlob) {
+ const reader = new FileReader();
+ await new Promise((resolve, reject) => {
+ reader.onload = resolve;
+ reader.onerror = reject;
+ reader.readAsDataURL(domainImageBlob);
+ });
+ const imageBase: string = reader.result && typeof reader.result === 'string' ? reader.result : '';
+ localStorage.setItem('domainThumbs', JSON.stringify({ ...domThumbs, [domain]: imageBase }));
+ return imageBase;
+ }
+ return false;
+ } catch (error) {
+ return false;
+ }
+ } else if (domThumbs[domain]) {
+ return domThumbs[domain];
+ }
+
+ return false;
+}
+
export function useFetchDomains(router: NextRouter, withStats:boolean = false) {
return useQuery('domains', () => fetchDomains(router, withStats));
}
diff --git a/types.d.ts b/types.d.ts
index 366c4f3..957c1d8 100644
--- a/types.d.ts
+++ b/types.d.ts
@@ -83,7 +83,8 @@ type SettingsType = {
scrape_delay?: string,
scrape_retry?: boolean,
failed_queue?: string[]
- version?: string
+ version?: string,
+ screenshot_key?: string,
}
type KeywordSCDataChild = {