More robust check of whether release notes exist (#175)
This commit is contained in:
59
src/ipc/handlers/release_note_handlers.ts
Normal file
59
src/ipc/handlers/release_note_handlers.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import log from "electron-log";
|
||||||
|
import fetch from "node-fetch";
|
||||||
|
import { createLoggedHandler } from "./safe_handle";
|
||||||
|
import { DoesReleaseNoteExistParams } from "../ipc_types";
|
||||||
|
|
||||||
|
const logger = log.scope("release_note_handlers");
|
||||||
|
|
||||||
|
const handle = createLoggedHandler(logger);
|
||||||
|
|
||||||
|
export function registerReleaseNoteHandlers() {
|
||||||
|
handle(
|
||||||
|
"does-release-note-exist",
|
||||||
|
async (_, params: DoesReleaseNoteExistParams) => {
|
||||||
|
const { version } = params;
|
||||||
|
|
||||||
|
if (!version || typeof version !== "string") {
|
||||||
|
throw new Error("Invalid version provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
const releaseNoteUrl = `https://www.dyad.sh/docs/releases/${version}`;
|
||||||
|
|
||||||
|
logger.debug(`Checking for release note at: ${releaseNoteUrl}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(releaseNoteUrl, { method: "HEAD" }); // Use HEAD to check existence without downloading content
|
||||||
|
if (response.ok) {
|
||||||
|
logger.debug(
|
||||||
|
`Release note found for version ${version} at ${releaseNoteUrl}`,
|
||||||
|
);
|
||||||
|
return { exists: true, url: releaseNoteUrl };
|
||||||
|
} else if (response.status === 404) {
|
||||||
|
logger.debug(
|
||||||
|
`Release note not found for version ${version} at ${releaseNoteUrl}`,
|
||||||
|
);
|
||||||
|
return { exists: false };
|
||||||
|
} else {
|
||||||
|
// Log other non-404 errors but still treat as "not found" for the client,
|
||||||
|
// as the primary goal is to check existence.
|
||||||
|
logger.warn(
|
||||||
|
`Unexpected status code ${response.status} when checking for release note: ${releaseNoteUrl}`,
|
||||||
|
);
|
||||||
|
return { exists: false };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(
|
||||||
|
`Error fetching release note for version ${version} at ${releaseNoteUrl}:`,
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
// In case of network errors, etc., assume it doesn't exist or is inaccessible.
|
||||||
|
// Throwing an error here would propagate to the client and might be too disruptive
|
||||||
|
// if the check is just for UI purposes (e.g., showing a link).
|
||||||
|
// Consider if specific errors should be thrown based on requirements.
|
||||||
|
return { exists: false };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.debug("Registered release note IPC handlers");
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import type {
|
|||||||
LanguageModel,
|
LanguageModel,
|
||||||
CreateCustomLanguageModelProviderParams,
|
CreateCustomLanguageModelProviderParams,
|
||||||
CreateCustomLanguageModelParams,
|
CreateCustomLanguageModelParams,
|
||||||
|
DoesReleaseNoteExistParams,
|
||||||
} from "./ipc_types";
|
} from "./ipc_types";
|
||||||
import type { ProposalResult } from "@/lib/schemas";
|
import type { ProposalResult } from "@/lib/schemas";
|
||||||
import { showError } from "@/lib/toast";
|
import { showError } from "@/lib/toast";
|
||||||
@@ -736,6 +737,12 @@ export class IpcClient {
|
|||||||
return this.ipcRenderer.invoke("get-system-platform");
|
return this.ipcRenderer.invoke("get-system-platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async doesReleaseNoteExist(
|
||||||
|
params: DoesReleaseNoteExistParams,
|
||||||
|
): Promise<{ exists: boolean; url?: string }> {
|
||||||
|
return this.ipcRenderer.invoke("does-release-note-exist", params);
|
||||||
|
}
|
||||||
|
|
||||||
public async getLanguageModelProviders(): Promise<LanguageModelProvider[]> {
|
public async getLanguageModelProviders(): Promise<LanguageModelProvider[]> {
|
||||||
return this.ipcRenderer.invoke("get-language-model-providers");
|
return this.ipcRenderer.invoke("get-language-model-providers");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { registerWindowHandlers } from "./handlers/window_handlers";
|
|||||||
import { registerUploadHandlers } from "./handlers/upload_handlers";
|
import { registerUploadHandlers } from "./handlers/upload_handlers";
|
||||||
import { registerVersionHandlers } from "./handlers/version_handlers";
|
import { registerVersionHandlers } from "./handlers/version_handlers";
|
||||||
import { registerLanguageModelHandlers } from "./handlers/language_model_handlers";
|
import { registerLanguageModelHandlers } from "./handlers/language_model_handlers";
|
||||||
|
import { registerReleaseNoteHandlers } from "./handlers/release_note_handlers";
|
||||||
|
|
||||||
export function registerIpcHandlers() {
|
export function registerIpcHandlers() {
|
||||||
// Register all IPC handlers by category
|
// Register all IPC handlers by category
|
||||||
@@ -35,4 +36,5 @@ export function registerIpcHandlers() {
|
|||||||
registerUploadHandlers();
|
registerUploadHandlers();
|
||||||
registerVersionHandlers();
|
registerVersionHandlers();
|
||||||
registerLanguageModelHandlers();
|
registerLanguageModelHandlers();
|
||||||
|
registerReleaseNoteHandlers();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,3 +181,7 @@ export interface CreateCustomLanguageModelParams {
|
|||||||
maxOutputTokens?: number;
|
maxOutputTokens?: number;
|
||||||
contextWindow?: number;
|
contextWindow?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DoesReleaseNoteExistParams {
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,17 +58,25 @@ export default function HomePage() {
|
|||||||
lastShownReleaseNotesVersion: appVersion,
|
lastShownReleaseNotesVersion: appVersion,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if release notes exist for this version
|
try {
|
||||||
const url = `https://www.dyad.sh/docs/releases/${appVersion}`;
|
const result = await IpcClient.getInstance().doesReleaseNoteExist({
|
||||||
const exists = await checkPageExists(url);
|
version: appVersion,
|
||||||
if (exists) {
|
});
|
||||||
setReleaseUrl(url + "?hideHeader=true&theme=" + theme);
|
|
||||||
setReleaseNotesOpen(true);
|
if (result.exists && result.url) {
|
||||||
|
setReleaseUrl(result.url + "?hideHeader=true&theme=" + theme);
|
||||||
|
setReleaseNotesOpen(true);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(
|
||||||
|
"Unable to check if release note exists for: " + appVersion,
|
||||||
|
err,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
updateLastVersionLaunched();
|
updateLastVersionLaunched();
|
||||||
}, [appVersion, settings, updateSettings]);
|
}, [appVersion, settings, updateSettings, theme]);
|
||||||
|
|
||||||
// Get the appId from search params
|
// Get the appId from search params
|
||||||
const appId = search.appId ? Number(search.appId) : null;
|
const appId = search.appId ? Number(search.appId) : null;
|
||||||
@@ -251,15 +259,3 @@ export default function HomePage() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPageExists(url: string) {
|
|
||||||
return fetch(url, { mode: "no-cors" })
|
|
||||||
.then(() => {
|
|
||||||
// Promise resolved - resource likely exists
|
|
||||||
return true;
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
// Promise rejected - resource likely doesn't exist or network error
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ const validInvokeChannels = [
|
|||||||
"delete-chat",
|
"delete-chat",
|
||||||
"delete-messages",
|
"delete-messages",
|
||||||
"start-chat-stream",
|
"start-chat-stream",
|
||||||
|
"does-release-note-exist",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
// Add valid receive channels
|
// Add valid receive channels
|
||||||
|
|||||||
Reference in New Issue
Block a user