Files
desktop/lib/preload/preload.ts
2026-01-30 17:20:14 +02:00

159 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { contextBridge, ipcRenderer, shell } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'
import api from './api'
const applicationLoader = `
<div style="
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #ffffff;
margin-top: 40px;
text-align: center;
">
<div style="
width: 48px;
height: 48px;
border: 4px solid #333333;
border-top-color: #0071e3;
border-radius: 50%;
animation: spin 1s linear infinite;
"></div>
<style>
@keyframes spin {
to { transform: rotate(360deg); }
}
</style>
</div>
`;
const applicationError = `
<div style="
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Helvetica Neue', sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
height: 100vh;
color: #ffffff;
padding: 40px;
text-align: center;
">
<div style="
flex-direction: column;
align-items: center;
justify-content: center;
">
<div style="
font-size: 72px;
margin-bottom: 20px;
">
<svg width="64" height="64" zoomAndPan="magnify" viewBox="0 0 384 383.999986" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><clipPath id="ab9f3e3410"><path d="M 134 109 L 369.46875 109 L 369.46875 381.34375 L 134 381.34375 Z M 134 109 " clip-rule="nonzero"/></clipPath><clipPath id="39bead0a6b"><path d="M 14.71875 2.59375 L 249 2.59375 L 249 222 L 14.71875 222 Z M 14.71875 2.59375 " clip-rule="nonzero"/></clipPath></defs><g clip-path="url(#ab9f3e3410)"><path fill="#ffffff" d="M 254.15625 284.453125 C 288.414062 275.191406 316.179688 260.617188 337.414062 240.769531 C 358.632812 220.917969 369.257812 195.238281 369.257812 163.691406 L 369.257812 109.996094 L 249.550781 110.222656 L 249.550781 168.148438 C 249.550781 184.847656 241.75 198.195312 226.148438 208.21875 C 210.550781 218.226562 188.175781 223.234375 159.007812 223.234375 L 134.070312 223.234375 L 134.070312 300.996094 L 206.652344 381.429688 L 344.765625 381.429688 L 254.15625 284.453125 " fill-opacity="1" fill-rule="nonzero"/></g><g clip-path="url(#39bead0a6b)"><path fill="#ffffff" d="M 248.417969 109.257812 L 248.417969 2.605469 L 14.769531 2.605469 L 14.769531 221.519531 L 132.9375 221.519531 L 132.9375 109.257812 L 248.417969 109.257812 " fill-opacity="1" fill-rule="nonzero"/></g></svg>
</div>
<h1 style="
font-size: 32px;
font-weight: 600;
margin: 0 0 12px 0;
letter-spacing: -0.5px;
">Application Error</h1>
<p style="
font-size: 17px;
color: #a1a1a6;
margin: 0 0 32px 0;
max-width: 500px;
line-height: 1.5;
">The application failed to load properly. Please wait for application repairing or reinstall application.</p>
${applicationLoader}
</div>
<div style="
display: flex;
flex-direction: row;
gap: 8px;
justify-content: center;
align-items: center;
">
<p style="
font-size: 13px;
color: #5a5a5f;
">rosetta - powering freedom. visit about rosetta-im.com. error: boot_process_failed</p>
</div>
</div>
`;
const exposeContext = async () => {
let version = await ipcRenderer.invoke("get-core-version");
let appPath = await ipcRenderer.invoke("get-app-path");
let arch = await ipcRenderer.invoke("get-arch");
let deviceName = await ipcRenderer.invoke("device:name");
let deviceId = await ipcRenderer.invoke("device:id");
let interval : any = 0;
interval = setInterval(() => {
/**
* Если после определенного таймаута приложение так и
* не загрузилось, то считаем, что процесс завис,
* и показываем экран ошибки. Так же отправляем
* сигнал в main процесс, чтобы тот мог попытаться
* откатить обновление
*/
if (document.body.innerHTML.indexOf("preloadersignature") !== -1) {
/**
* Если сейчас показывается прелоадер, то не считаем
* что обновление битое, так как само обновление еще не
* загрузилось в приложение
*/
return;
}
if (document.body.innerHTML.length < 100) {
/**
* Приложение загружено, а прошло больше 5 секунд
* с момента прелоадера, значит что-то пошло не так
* и нужно показать экран ошибки
*/
document.body.innerHTML = applicationError;
ipcRenderer.invoke("report-boot-process-failed");
}
clearInterval(interval);
}, 5000);
let downloadsPath = await ipcRenderer.invoke("get-downloads-path");
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('electron', electronAPI)
contextBridge.exposeInMainWorld('api', api)
contextBridge.exposeInMainWorld('version', version);
contextBridge.exposeInMainWorld('platform', process.platform);
contextBridge.exposeInMainWorld('appPath', appPath);
contextBridge.exposeInMainWorld('arch', arch);
contextBridge.exposeInMainWorld('deviceName', deviceName);
contextBridge.exposeInMainWorld('deviceId', deviceId);
contextBridge.exposeInMainWorld('shell', {
openExternal: (url: string) => {
ipcRenderer.invoke('openExternal', url);
},
showItemInFolder: (fullPath: string) => {
ipcRenderer.invoke('showItemInFolder', fullPath);
}
});
contextBridge.exposeInMainWorld('downloadsPath', downloadsPath)
} catch (error) {
console.error(error)
}
} else {
window.electron = electronAPI
window.api = api
window.version = version;
window.platform = process.platform;
window.appPath = appPath;
window.arch = arch;
window.shell = shell;
window.downloadsPath = downloadsPath;
window.deviceName = deviceName;
window.deviceId = deviceId;
}
}
exposeContext();