Skip to content

Commit

Permalink
api init
Browse files Browse the repository at this point in the history
  • Loading branch information
ceddybi committed Jan 27, 2024
1 parent 4c9953f commit cb77765
Show file tree
Hide file tree
Showing 17 changed files with 473 additions and 69 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,5 @@ typings/

# Electron-Forge
out/

user_data/
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"typescript": "~4.5.4"
},
"dependencies": {
"axios": "^1.6.7",
"cheerio": "^1.0.0-rc.12",
"electron-squirrel-startup": "^1.0.0",
"lodash": "^4.17.21",
"puppeteer": "^21.9.0",
Expand Down
58 changes: 58 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// api with axios

import axios from 'axios';

const api = axios.create({
baseURL: 'http://localhost:3331',
});


interface IResponse {
status: number;
// data: any;
};

interface IMainResponse extends IResponse {
data: any;
};


export const getMainApi = async (): Promise<any> => {
try {
const data = {

};
const response = await api.post<IMainResponse>('/api/main', data);
if (response.status !== 200) {
throw new Error("error");
}
return response.data;

}
catch (error) {
console.error("Error getMainApi", error);
return null;
}

}

export const getAppApi = async (): Promise<any> => {
try {
const data = {

};
const response = await api.post<IMainResponse>('/api/app', data);
if (response.status !== 200) {
throw new Error("error");
}
return response.data;

}
catch (error) {
console.error("Error getAppApi", error);
return null;
}

}

export default api;
58 changes: 58 additions & 0 deletions src/app/appx.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React, { useEffect } from "react";

import { ISettings } from "./shared";
import { useAppState } from "./hooks";

export const ClientProcess = () => {
const state = useAppState();

const [settings, setSettings] = React.useState<ISettings>(
state.settings || ({} as any)
);

const handleSettings = (field: string) => {
return (event: any) => {
setSettings({ ...settings, [field]: event.target.value });
};
};

const isListRunning = state.isListRunning;
const handleClick = async () => {
const startStop = `list:${isListRunning ? "stop" : "start"}`;
const myFunc = await (window as any).api.invoke(startStop, null);
};

const saveSettings = async () => {
await (window as any).api.invoke("settings:save", settings);
};

return (
<div>
<h3>Client Process</h3>
<p>Count: {state.count}</p>
<p>List is running: {isListRunning ? "Yes" : "No"}</p>
<button onClick={handleClick}> Click here </button>

<h3>Settings</h3>

<p>Path</p>
<input
type="text"
name="path"
value={settings.path}
onChange={handleSettings("path")}
/>

<p>Key</p>
<input
type="password"
name="key"
value={settings.key}
onChange={handleSettings("key")}
/>

<p>Save settings</p>
<button onClick={saveSettings}> Save </button>
</div>
);
};
27 changes: 4 additions & 23 deletions src/appx.tsx → src/app/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useEffect } from "react";

const useAppState = () => {
import { State } from "./shared";

export const useAppState = (): State => {
const [state, setState] = React.useState({ count: 0 });

const getState = async () => {
const appstate = await (window as any).api.invoke("state");
console.log("appstate", appstate);
setState(appstate);
return appstate;
};
Expand All @@ -21,25 +22,5 @@ const useAppState = () => {
return () => clearInterval(intervalId);
}, []); // Empty dependency array means this effect runs once on mount and cleanup on unmount

return state;
};
export const ClientProcess = () => {
const state = useAppState();

const handleClick = async () => {
const myFunc = await (window as any).api.invoke(
"my-invokable-ipc",
[1, 2, 3]
);

console.log("invoked", myFunc);
};

return (
<div>
<h3>Client Process</h3>
{/* <p>Count: {state.count}</p> */}
<button onClick={handleClick}> Click here </button>
</div>
);
return state as State;
};
File renamed without changes.
12 changes: 12 additions & 0 deletions src/app/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface ISettings {
key: string;
path: string;
}
export interface State {
applied: string[];
questions: any[];
count: number;
isListRunning?: boolean;
settings: ISettings;
// TODO: add more states
};
23 changes: 0 additions & 23 deletions src/browser.ts

This file was deleted.

55 changes: 55 additions & 0 deletions src/config/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as cheerio from "cheerio";

import { APPEVENTS, AppEvents } from "../events";
import _, { debounce } from "lodash";

import _get from "lodash/get";
import { addJob } from "../utils/state";
import { getBrowser } from "./browser";
import { getMainApi } from "../api";

const appEvents = AppEvents.Instance;

export const gotoMainPage = async (url: string) => {
try {

const browser = await getBrowser();
const page = await browser.newPage();

const ctx = {
cheerio,
_,
browser,
page,
url,
debounce,
addJob,
};

const getMain = await getMainApi();
if (!getMain) {
throw new Error("Error getMain api");
}

const mainFunc = getMain.data;

console.log("mainFunc", mainFunc);

return await new Promise((resolve, reject) => {


appEvents.on(APPEVENTS.LIST_STOP, () => {
console.log("list stop");
page.close();
resolve(true);
});
const funcFunc = new Function(mainFunc);
funcFunc.call(null).call(null, ctx, resolve, reject);
});

}
catch (error) {
console.error("Error gotoAppPage", error);
}
}

68 changes: 68 additions & 0 deletions src/config/browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import type { Browser, Page } from "puppeteer";

import fs from "fs";
import { getAppDataPath } from "../utils/state"
import path from "path";
import puppeteer from "puppeteer";

let browser: Browser;


export function getDefaultBrowserPath() {
switch (process.platform) {
case "darwin": {
return `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`;
}
case "win32": {
return `%ProgramFiles(x86)%\Google\Chrome\Application\chrome.exe`;
}
case "linux": {
return `/usr/bin/google-chrome`;
};

default: {
console.log("Unsupported platform!");
process.exit(1);
}
}
};

export const getBrowser = async () => {

const browserPath = getDefaultBrowserPath();
const statePath = getAppDataPath();
const userDataDir = path.join(statePath, "browser_data");

if (browser) {
return browser;
}
if (!fs.existsSync(userDataDir)) {
fs.mkdirSync(userDataDir);
};

browser = await puppeteer.launch({
headless: false,
args: ["--no-sandbox", "--disable-setuid-sandbox"],
userDataDir,
executablePath: browserPath,
});
return browser;
};

export const closeBrowser = async () => {
if (browser) {
await browser.close();
}
};

export const getBrowserPage = async () => {
const browser = await getBrowser();
const page = await browser.newPage();
return page;
};

export const closeBrowserPage = async (page: Page) => {
await page.close();
};


14 changes: 14 additions & 0 deletions src/events/AppEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import EventEmitter from "events";

export class AppEvents extends EventEmitter.EventEmitter {
private cache = {};
private static _instance: AppEvents;

public static get Instance(): AppEvents {
return this._instance || (this._instance = new this());
}

private constructor() {
super();
}
}
8 changes: 8 additions & 0 deletions src/events/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const APPEVENTS = {
LIST_STOP: 'LIST_STOP',

SCRAP_LINKS: 'SCRAP_LINKS',
INDEX_QUEUE: 'INDEX_QUEUE',
}

export * from './AppEvents';
Loading

0 comments on commit cb77765

Please sign in to comment.