mirror of
https://github.com/ivabus/gui
synced 2025-04-23 14:07:14 +03:00
move auth polling strategy to main thread (#546)
* #545 move auth polling strategy to main thread * #545 remove unused * bum v0.1.1 --------- Co-authored-by: neil molina <neil@neils-MacBook-Pro.local>
This commit is contained in:
parent
1a0289f7c1
commit
9f88a1bf5b
8 changed files with 84 additions and 66 deletions
|
@ -196,7 +196,7 @@ app.on("open-url", (event, url) => {
|
|||
}
|
||||
});
|
||||
|
||||
function notifyMainWindow(channel: string, data: unknown) {
|
||||
export function notifyMainWindow(channel: string, data: unknown) {
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.webContents.send(channel, data);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ import { getTeaPath } from "./tea-dir";
|
|||
import { app } from "electron";
|
||||
import log from "./logger";
|
||||
import axios from "axios";
|
||||
import get from "./v1-client";
|
||||
import { DeviceAuth } from "../../src/libs/types";
|
||||
import { notifyMainWindow } from "../electron";
|
||||
|
||||
const sessionFilePath = path.join(getTeaPath(), "tea.xyz/gui/tmp.dat");
|
||||
const sessionFolder = path.join(getTeaPath(), "tea.xyz/gui");
|
||||
|
@ -152,3 +155,44 @@ export async function writeSessionData(data: Session, force?: boolean) {
|
|||
log.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
let pollInterval: NodeJS.Timer | null;
|
||||
let pollLoop = 0;
|
||||
export async function pollAuth() {
|
||||
if (!pollInterval) {
|
||||
log.info("polling auth starts...");
|
||||
const session = await readSessionData();
|
||||
pollInterval = setInterval(async () => {
|
||||
pollLoop++;
|
||||
log.info("poll auth retry:", pollLoop);
|
||||
let clear = false;
|
||||
let success = false;
|
||||
try {
|
||||
const data = await get<DeviceAuth>(`/auth/device/${session.device_id}`);
|
||||
if (data?.status === "SUCCESS") {
|
||||
await writeSessionData({
|
||||
key: data.key,
|
||||
user: data.user
|
||||
});
|
||||
clear = true;
|
||||
success = true;
|
||||
} else if (pollLoop > 20 && pollInterval) {
|
||||
clear = true;
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
clear = true;
|
||||
} finally {
|
||||
if (clear) {
|
||||
pollInterval && clearInterval(pollInterval);
|
||||
pollInterval = null;
|
||||
log.info("polling auth ends.");
|
||||
}
|
||||
if (success) {
|
||||
log.info("updating renderer session");
|
||||
notifyMainWindow("session-update", sessionMemory);
|
||||
}
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ipcMain, app, BrowserWindow } from "electron";
|
||||
import { deletePackageFolder, getInstalledPackages, cacheImage } from "./tea-dir";
|
||||
import { readSessionData, writeSessionData } from "./auth";
|
||||
import { readSessionData, writeSessionData, pollAuth } from "./auth";
|
||||
import type { Packages, Session } from "../../src/libs/types";
|
||||
import log from "./logger";
|
||||
import { syncLogsAt } from "./v1-client";
|
||||
|
@ -205,4 +205,13 @@ export default function initializeHandlers({ notifyMainWindow }: HandlerOptions)
|
|||
log.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle("poll-session", async () => {
|
||||
try {
|
||||
log.info("start polling");
|
||||
return pollAuth();
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "tea",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"description": "tea gui app",
|
||||
"author": "tea.xyz",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { authStore, navStore } from "$libs/stores";
|
||||
import { authStore } from "$libs/stores";
|
||||
import { getSession } from "@native";
|
||||
import { baseUrl } from "$libs/v1-client";
|
||||
import { shellOpenExternal } from "@native";
|
||||
import { shellOpenExternal, pollDeviceSession } from "@native";
|
||||
import mouseLeaveDelay from "@tea/ui/lib/mouse-leave-delay";
|
||||
const { user } = authStore;
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
|||
|
||||
if (session && session.device_id) {
|
||||
shellOpenExternal(`${baseUrl}/auth/user?device_id=${session.device_id}`);
|
||||
authStore.pollSession();
|
||||
pollDeviceSession();
|
||||
} else {
|
||||
throw new Error("possible no internet connection");
|
||||
}
|
||||
|
|
|
@ -12,14 +12,7 @@
|
|||
*/
|
||||
|
||||
import type { Package, Review, AirtablePost, Bottle } from "@tea/ui/types";
|
||||
import {
|
||||
type GUIPackage,
|
||||
type DeviceAuth,
|
||||
type Session,
|
||||
AuthStatus,
|
||||
type Packages,
|
||||
type AutoUpdateStatus
|
||||
} from "./types";
|
||||
import type { GUIPackage, Session, Packages, AutoUpdateStatus } from "./types";
|
||||
|
||||
import * as mock from "./native-mock";
|
||||
import { PackageStates, type InstalledPackage } from "./types";
|
||||
|
@ -130,21 +123,6 @@ export async function getAllPosts(tag?: string): Promise<AirtablePost[]> {
|
|||
}
|
||||
}
|
||||
|
||||
export async function getDeviceAuth(deviceId: string): Promise<DeviceAuth> {
|
||||
let auth: DeviceAuth = {
|
||||
status: AuthStatus.UNKNOWN,
|
||||
key: ""
|
||||
};
|
||||
try {
|
||||
const data = await apiGet<DeviceAuth>(`/auth/device/${deviceId}`);
|
||||
if (data) auth = data;
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
auth = await getDeviceAuth(deviceId);
|
||||
}
|
||||
return auth;
|
||||
}
|
||||
|
||||
export async function getPackageBottles(packageName: string): Promise<Bottle[]> {
|
||||
try {
|
||||
return withRetry(async () => {
|
||||
|
@ -296,3 +274,11 @@ export const getAutoUpdateStatus = async (): Promise<AutoUpdateStatus> => {
|
|||
return { status: "up-to-date" };
|
||||
}
|
||||
};
|
||||
|
||||
export const pollDeviceSession = async () => {
|
||||
try {
|
||||
await ipcRenderer.invoke("poll-session");
|
||||
} catch (error) {
|
||||
log.error(error);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -326,11 +326,6 @@ export async function getAllPosts(type: string): Promise<AirtablePost[]> {
|
|||
return posts;
|
||||
}
|
||||
|
||||
export async function getDeviceAuth(deviceId: string): Promise<any> {
|
||||
const data = await v1Client.get<any>(`/auth/device/${deviceId}`);
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function getPackageBottles(name: string): Promise<Bottle[]> {
|
||||
return [
|
||||
{ name, platform: "darwin", arch: "aarch64", version: "3.39.4", bytes: 123456 },
|
||||
|
@ -411,3 +406,7 @@ export const getAutoUpdateStatus = async (): Promise<AutoUpdateStatus> => {
|
|||
export async function openPackageEntrypointInTerminal(pkg: string) {
|
||||
//noop
|
||||
}
|
||||
|
||||
export const pollDeviceSession = async () => {
|
||||
console.log("do nothing");
|
||||
};
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { writable } from "svelte/store";
|
||||
|
||||
import { getDeviceAuth } from "@native";
|
||||
import { listenToChannel } from "@native";
|
||||
import type { Developer } from "@tea/ui/types";
|
||||
import type { Session } from "$libs/types";
|
||||
import { getSession as electronGetSession, updateSession as electronUpdateSession } from "@native";
|
||||
import { initSentry } from "../sentry";
|
||||
import log from "$libs/logger";
|
||||
|
||||
export let session: Session | null = null;
|
||||
export const getSession = async (): Promise<Session | null> => {
|
||||
|
@ -15,7 +16,6 @@ export const getSession = async (): Promise<Session | null> => {
|
|||
export default function initAuthStore() {
|
||||
const user = writable<Developer | undefined>();
|
||||
const sessionStore = writable<Session>({});
|
||||
let pollLoop = 0;
|
||||
|
||||
const deviceIdStore = writable<string>("");
|
||||
let deviceId = "";
|
||||
|
@ -31,7 +31,16 @@ export default function initAuthStore() {
|
|||
}
|
||||
});
|
||||
|
||||
let timer: NodeJS.Timer | null;
|
||||
listenToChannel("session-update", (data: Session) => {
|
||||
log.info("session update renderer", data);
|
||||
sessionStore.update((val) => ({
|
||||
...val,
|
||||
...data
|
||||
}));
|
||||
if (data.user) {
|
||||
user.set(data.user);
|
||||
}
|
||||
});
|
||||
|
||||
async function updateSession(data: Session) {
|
||||
sessionStore.update((val) => ({
|
||||
|
@ -43,34 +52,6 @@ export default function initAuthStore() {
|
|||
await electronUpdateSession(data);
|
||||
}
|
||||
|
||||
async function pollSession() {
|
||||
if (!timer) {
|
||||
timer = setInterval(async () => {
|
||||
pollLoop++;
|
||||
try {
|
||||
const data = await getDeviceAuth(deviceId);
|
||||
if (data.status === "SUCCESS") {
|
||||
updateSession({
|
||||
key: data.key,
|
||||
user: data.user
|
||||
});
|
||||
user.set(data.user!);
|
||||
timer && clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
if (pollLoop > 20 && timer) {
|
||||
clearInterval(timer);
|
||||
pollLoop = 0;
|
||||
timer = null;
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
function clearSession() {
|
||||
updateSession({ key: undefined, user: undefined });
|
||||
user.set(undefined);
|
||||
|
@ -81,7 +62,6 @@ export default function initAuthStore() {
|
|||
session: sessionStore,
|
||||
deviceId,
|
||||
deviceIdStore,
|
||||
pollSession,
|
||||
clearSession,
|
||||
updateSession
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue