mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-04 02:31:36 +00:00
style(desktop): format gitnexus-desktop package
This commit is contained in:
parent
6c644e3b17
commit
21fb1b9a0c
13 changed files with 147 additions and 75 deletions
|
|
@ -51,4 +51,4 @@ linux:
|
|||
- AppImage
|
||||
nsis:
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
allowToChangeInstallationDirectory: true
|
||||
|
|
|
|||
|
|
@ -45,4 +45,4 @@ export default {
|
|||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,4 +34,4 @@
|
|||
"typescript": "^6.0.3",
|
||||
"vite": "^7.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,9 @@ const ensureDesktopRendererPortAvailable = () => {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
console.info(`Stopping stale desktop renderer process on port ${desktopRendererPort} (PID ${owner.pid}).`);
|
||||
console.info(
|
||||
`Stopping stale desktop renderer process on port ${desktopRendererPort} (PID ${owner.pid}).`,
|
||||
);
|
||||
killProcessTree(owner.pid);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,18 +11,32 @@ const workspaceRoot = path.resolve(packageRoot, '..');
|
|||
const gitnexusRoot = path.join(workspaceRoot, 'gitnexus');
|
||||
const gitnexusWebRoot = path.join(workspaceRoot, 'gitnexus-web');
|
||||
const releaseRoot = path.join(packageRoot, 'release');
|
||||
const desktopPackageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
|
||||
const desktopPackageLock = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package-lock.json'), 'utf8'));
|
||||
const electronVersion = desktopPackageJson.devDependencies?.electron?.replace(/^[^\d]*/, '') ?? '41.2.1';
|
||||
const electronBuilderVersion = desktopPackageJson.devDependencies?.['electron-builder']?.replace(/^[^\d]*/, '') ?? '26.8.1';
|
||||
const desktopPackageJson = JSON.parse(
|
||||
fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'),
|
||||
);
|
||||
const desktopPackageLock = JSON.parse(
|
||||
fs.readFileSync(path.join(packageRoot, 'package-lock.json'), 'utf8'),
|
||||
);
|
||||
const electronVersion =
|
||||
desktopPackageJson.devDependencies?.electron?.replace(/^[^\d]*/, '') ?? '41.2.1';
|
||||
const electronBuilderVersion =
|
||||
desktopPackageJson.devDependencies?.['electron-builder']?.replace(/^[^\d]*/, '') ?? '26.8.1';
|
||||
const appBuilderLibVersion =
|
||||
desktopPackageLock.packages?.['node_modules/app-builder-lib']?.version ?? electronBuilderVersion.replace(/^[^\d]*/, '');
|
||||
desktopPackageLock.packages?.['node_modules/app-builder-lib']?.version ??
|
||||
electronBuilderVersion.replace(/^[^\d]*/, '');
|
||||
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||
const outputDir = path.join(releaseRoot, stamp);
|
||||
const generatedBuilderConfigPath = path.join(outputDir, 'electron-builder.generated.json');
|
||||
const requiredNsisTemplateFiles = [
|
||||
path.join(packageRoot, 'node_modules', 'app-builder-lib', 'templates', 'nsis', 'messages.yml'),
|
||||
path.join(packageRoot, 'node_modules', 'app-builder-lib', 'templates', 'nsis', 'assistedMessages.yml'),
|
||||
path.join(
|
||||
packageRoot,
|
||||
'node_modules',
|
||||
'app-builder-lib',
|
||||
'templates',
|
||||
'nsis',
|
||||
'assistedMessages.yml',
|
||||
),
|
||||
];
|
||||
const supportedTargetHosts = {
|
||||
'--linux': 'linux',
|
||||
|
|
@ -142,7 +156,9 @@ const overlayDirectoryContents = (sourceDirectory, destinationDirectory) => {
|
|||
};
|
||||
|
||||
const repairAppBuilderLibPackage = () => {
|
||||
const repairDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'gitnexus-desktop-app-builder-lib-'));
|
||||
const repairDirectory = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), 'gitnexus-desktop-app-builder-lib-'),
|
||||
);
|
||||
|
||||
try {
|
||||
const tarballName = `app-builder-lib-${appBuilderLibVersion}.tgz`;
|
||||
|
|
@ -150,7 +166,10 @@ const repairAppBuilderLibPackage = () => {
|
|||
const extractedPackageRoot = path.join(repairDirectory, 'package');
|
||||
const installedPackageRoot = path.join(packageRoot, 'node_modules', 'app-builder-lib');
|
||||
|
||||
runCommand(`npm pack app-builder-lib@${appBuilderLibVersion} --pack-destination "${repairDirectory}"`, packageRoot);
|
||||
runCommand(
|
||||
`npm pack app-builder-lib@${appBuilderLibVersion} --pack-destination "${repairDirectory}"`,
|
||||
packageRoot,
|
||||
);
|
||||
runCommand(`tar -xzf "${tarballPath}" -C "${repairDirectory}"`, packageRoot);
|
||||
overlayDirectoryContents(extractedPackageRoot, installedPackageRoot);
|
||||
} finally {
|
||||
|
|
@ -159,7 +178,9 @@ const repairAppBuilderLibPackage = () => {
|
|||
};
|
||||
|
||||
const assertSupportedHostForRequestedTargets = () => {
|
||||
const unsupportedTargets = requestedTargets.filter((target) => supportedTargetHosts[target] !== process.platform);
|
||||
const unsupportedTargets = requestedTargets.filter(
|
||||
(target) => supportedTargetHosts[target] !== process.platform,
|
||||
);
|
||||
|
||||
if (unsupportedTargets.length === 0) {
|
||||
return;
|
||||
|
|
@ -185,13 +206,17 @@ const ensureDesktopToolchainHealthy = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
const missingNsisTemplates = requiredNsisTemplateFiles.filter((filePath) => !fs.existsSync(filePath));
|
||||
const missingNsisTemplates = requiredNsisTemplateFiles.filter(
|
||||
(filePath) => !fs.existsSync(filePath),
|
||||
);
|
||||
|
||||
if (missingNsisTemplates.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn('[build] electron-builder NSIS templates are missing. Restoring app-builder-lib package contents first...');
|
||||
console.warn(
|
||||
'[build] electron-builder NSIS templates are missing. Restoring app-builder-lib package contents first...',
|
||||
);
|
||||
|
||||
try {
|
||||
repairAppBuilderLibPackage();
|
||||
|
|
@ -203,7 +228,9 @@ const ensureDesktopToolchainHealthy = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
console.warn('[build] Package overlay repair was not enough. Reinstalling electron-builder next...');
|
||||
console.warn(
|
||||
'[build] Package overlay repair was not enough. Reinstalling electron-builder next...',
|
||||
);
|
||||
|
||||
const targetedRepairWorked = tryRunCommand(
|
||||
`npm install --no-save --package-lock=false electron-builder@${electronBuilderVersion}`,
|
||||
|
|
@ -218,7 +245,9 @@ const ensureDesktopToolchainHealthy = () => {
|
|||
runCommand('npm ci', packageRoot);
|
||||
}
|
||||
|
||||
const unresolvedTemplates = requiredNsisTemplateFiles.filter((filePath) => !fs.existsSync(filePath));
|
||||
const unresolvedTemplates = requiredNsisTemplateFiles.filter(
|
||||
(filePath) => !fs.existsSync(filePath),
|
||||
);
|
||||
|
||||
if (unresolvedTemplates.length > 0) {
|
||||
throw new Error(
|
||||
|
|
@ -275,4 +304,4 @@ if (artifacts.length > 0) {
|
|||
for (const artifact of artifacts) {
|
||||
console.log(` - ${artifact}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,7 +209,11 @@ const isAnyHttpUrlReady = async (urls: string[], expectedMarkers?: string[]): Pr
|
|||
return false;
|
||||
};
|
||||
|
||||
const waitForUrlReady = async (url: string, timeoutMs: number, expectedMarkers?: string[]): Promise<void> => {
|
||||
const waitForUrlReady = async (
|
||||
url: string,
|
||||
timeoutMs: number,
|
||||
expectedMarkers?: string[],
|
||||
): Promise<void> => {
|
||||
const deadline = Date.now() + timeoutMs;
|
||||
|
||||
while (Date.now() < deadline) {
|
||||
|
|
@ -250,18 +254,26 @@ const getGitNexusWebDevRoot = (): string => {
|
|||
};
|
||||
|
||||
const getNodeCommand = (): string => {
|
||||
return process.env.npm_node_execpath || process.env.NODE || (process.platform === 'win32' ? 'node.exe' : 'node');
|
||||
return (
|
||||
process.env.npm_node_execpath ||
|
||||
process.env.NODE ||
|
||||
(process.platform === 'win32' ? 'node.exe' : 'node')
|
||||
);
|
||||
};
|
||||
|
||||
const spawnGitNexusServer = (): ChildProcess => {
|
||||
const childProcess = spawn(getNodeCommand(), [getGitNexusCliEntry(), 'serve', '--host', GITNEXUS_HOST], {
|
||||
cwd: getGitNexusRuntimeDir(),
|
||||
env: {
|
||||
...process.env,
|
||||
const childProcess = spawn(
|
||||
getNodeCommand(),
|
||||
[getGitNexusCliEntry(), 'serve', '--host', GITNEXUS_HOST],
|
||||
{
|
||||
cwd: getGitNexusRuntimeDir(),
|
||||
env: {
|
||||
...process.env,
|
||||
},
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
windowsHide: true,
|
||||
},
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
windowsHide: true,
|
||||
});
|
||||
);
|
||||
|
||||
childProcess.stdout?.on('data', (chunk) => {
|
||||
appendGitNexusServerOutput(chunk);
|
||||
|
|
@ -312,8 +324,22 @@ const spawnWebDevServer = (): ChildProcess => {
|
|||
const command = process.platform === 'win32' ? 'cmd.exe' : 'npm';
|
||||
const args =
|
||||
process.platform === 'win32'
|
||||
? ['/d', '/s', '/c', `npm run dev -- --host ${GITNEXUS_WEB_DEV_HOST} --port ${GITNEXUS_WEB_DEV_PORT} --strictPort`]
|
||||
: ['run', 'dev', '--', '--host', GITNEXUS_WEB_DEV_HOST, '--port', String(GITNEXUS_WEB_DEV_PORT), '--strictPort'];
|
||||
? [
|
||||
'/d',
|
||||
'/s',
|
||||
'/c',
|
||||
`npm run dev -- --host ${GITNEXUS_WEB_DEV_HOST} --port ${GITNEXUS_WEB_DEV_PORT} --strictPort`,
|
||||
]
|
||||
: [
|
||||
'run',
|
||||
'dev',
|
||||
'--',
|
||||
'--host',
|
||||
GITNEXUS_WEB_DEV_HOST,
|
||||
'--port',
|
||||
String(GITNEXUS_WEB_DEV_PORT),
|
||||
'--strictPort',
|
||||
];
|
||||
|
||||
const childProcess = spawn(command, args, {
|
||||
cwd: getGitNexusWebDevRoot(),
|
||||
|
|
@ -352,7 +378,11 @@ const ensureWebDevServerStarted = async (): Promise<void> => {
|
|||
webDevServerProcess = spawnWebDevServer();
|
||||
}
|
||||
|
||||
await waitForUrlReady(GITNEXUS_WEB_DEV_URL, GITNEXUS_WEB_READY_TIMEOUT_MS, GITNEXUS_WEB_EXPECTED_MARKERS);
|
||||
await waitForUrlReady(
|
||||
GITNEXUS_WEB_DEV_URL,
|
||||
GITNEXUS_WEB_READY_TIMEOUT_MS,
|
||||
GITNEXUS_WEB_EXPECTED_MARKERS,
|
||||
);
|
||||
};
|
||||
|
||||
const normalizeStaticPath = (rootDir: string, requestPath: string): string | null => {
|
||||
|
|
@ -454,7 +484,11 @@ const stopWebDevServer = (): void => {
|
|||
};
|
||||
|
||||
const stopGitNexusServer = (): void => {
|
||||
if (!gitNexusServerProcess || !gitNexusServerProcess.pid || gitNexusServerProcess.exitCode !== null) {
|
||||
if (
|
||||
!gitNexusServerProcess ||
|
||||
!gitNexusServerProcess.pid ||
|
||||
gitNexusServerProcess.exitCode !== null
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -559,7 +593,9 @@ const createEmbeddedContentView = (contentUrl: string): BrowserView => {
|
|||
|
||||
contentView.webContents.on('dom-ready', () => {
|
||||
void contentView.webContents.insertCSS(EMBEDDED_APP_SCROLLBAR_CSS).catch((error) => {
|
||||
console.warn(`[gitnexus-desktop] Failed to inject embedded app CSS: ${getErrorMessage(error)}`);
|
||||
console.warn(
|
||||
`[gitnexus-desktop] Failed to inject embedded app CSS: ${getErrorMessage(error)}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -761,4 +797,4 @@ app.on('window-all-closed', () => {
|
|||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,47 +7,50 @@ const DESKTOP_WINDOW_STATE_CHANGED_CHANNEL = 'gitnexus-desktop:window-state-chan
|
|||
const DESKTOP_SHELL_TITLEBAR_HEIGHT = process.platform === 'darwin' ? 38 : 0;
|
||||
|
||||
type DesktopShellState = {
|
||||
appName: string;
|
||||
isAlwaysOnTop: boolean;
|
||||
isMaximized: boolean;
|
||||
platform: NodeJS.Platform;
|
||||
titleBarHeight: number;
|
||||
appName: string;
|
||||
isAlwaysOnTop: boolean;
|
||||
isMaximized: boolean;
|
||||
platform: NodeJS.Platform;
|
||||
titleBarHeight: number;
|
||||
};
|
||||
|
||||
type DesktopWindowAction = 'close' | 'minimize' | 'toggle-always-on-top' | 'toggle-maximize';
|
||||
|
||||
const invokeWindowAction = (action: DesktopWindowAction): Promise<DesktopShellState | null> => {
|
||||
return ipcRenderer.invoke(DESKTOP_WINDOW_ACTION_CHANNEL, action) as Promise<DesktopShellState | null>;
|
||||
return ipcRenderer.invoke(
|
||||
DESKTOP_WINDOW_ACTION_CHANNEL,
|
||||
action,
|
||||
) as Promise<DesktopShellState | null>;
|
||||
};
|
||||
|
||||
contextBridge.exposeInMainWorld('gitnexusDesktop', {
|
||||
appName: DESKTOP_APP_NAME,
|
||||
platform: process.platform,
|
||||
titleBarHeight: DESKTOP_SHELL_TITLEBAR_HEIGHT,
|
||||
close: async (): Promise<void> => {
|
||||
await invokeWindowAction('close');
|
||||
},
|
||||
getShellState: (): Promise<DesktopShellState> => {
|
||||
return ipcRenderer.invoke(DESKTOP_GET_SHELL_STATE_CHANNEL) as Promise<DesktopShellState>;
|
||||
},
|
||||
minimize: (): Promise<DesktopShellState | null> => {
|
||||
return invokeWindowAction('minimize');
|
||||
},
|
||||
onWindowStateChanged: (callback: (state: DesktopShellState) => void): (() => void) => {
|
||||
const listener = (_event: IpcRendererEvent, state: DesktopShellState): void => {
|
||||
callback(state);
|
||||
};
|
||||
appName: DESKTOP_APP_NAME,
|
||||
platform: process.platform,
|
||||
titleBarHeight: DESKTOP_SHELL_TITLEBAR_HEIGHT,
|
||||
close: async (): Promise<void> => {
|
||||
await invokeWindowAction('close');
|
||||
},
|
||||
getShellState: (): Promise<DesktopShellState> => {
|
||||
return ipcRenderer.invoke(DESKTOP_GET_SHELL_STATE_CHANNEL) as Promise<DesktopShellState>;
|
||||
},
|
||||
minimize: (): Promise<DesktopShellState | null> => {
|
||||
return invokeWindowAction('minimize');
|
||||
},
|
||||
onWindowStateChanged: (callback: (state: DesktopShellState) => void): (() => void) => {
|
||||
const listener = (_event: IpcRendererEvent, state: DesktopShellState): void => {
|
||||
callback(state);
|
||||
};
|
||||
|
||||
ipcRenderer.on(DESKTOP_WINDOW_STATE_CHANGED_CHANNEL, listener);
|
||||
ipcRenderer.on(DESKTOP_WINDOW_STATE_CHANGED_CHANNEL, listener);
|
||||
|
||||
return () => {
|
||||
ipcRenderer.removeListener(DESKTOP_WINDOW_STATE_CHANGED_CHANNEL, listener);
|
||||
};
|
||||
},
|
||||
toggleAlwaysOnTop: (): Promise<DesktopShellState | null> => {
|
||||
return invokeWindowAction('toggle-always-on-top');
|
||||
},
|
||||
toggleMaximize: (): Promise<DesktopShellState | null> => {
|
||||
return invokeWindowAction('toggle-maximize');
|
||||
},
|
||||
});
|
||||
return () => {
|
||||
ipcRenderer.removeListener(DESKTOP_WINDOW_STATE_CHANGED_CHANNEL, listener);
|
||||
};
|
||||
},
|
||||
toggleAlwaysOnTop: (): Promise<DesktopShellState | null> => {
|
||||
return invokeWindowAction('toggle-always-on-top');
|
||||
},
|
||||
toggleMaximize: (): Promise<DesktopShellState | null> => {
|
||||
return invokeWindowAction('toggle-maximize');
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ const fallbackDesktopApi: DesktopApi = {
|
|||
toggleMaximize: async () => defaultDesktopState,
|
||||
};
|
||||
|
||||
const desktopApi = (window as Window & { gitnexusDesktop?: DesktopApi }).gitnexusDesktop ?? fallbackDesktopApi;
|
||||
const desktopApi =
|
||||
(window as Window & { gitnexusDesktop?: DesktopApi }).gitnexusDesktop ?? fallbackDesktopApi;
|
||||
|
||||
const styles = `
|
||||
:root {
|
||||
|
|
@ -352,4 +353,4 @@ export default function App() {
|
|||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ const fallbackDesktopApi: DesktopApi = {
|
|||
toggleMaximize: async () => defaultDesktopState,
|
||||
};
|
||||
|
||||
const desktopApi = (window as Window & { gitnexusDesktop?: DesktopApi }).gitnexusDesktop ?? fallbackDesktopApi;
|
||||
const desktopApi =
|
||||
(window as Window & { gitnexusDesktop?: DesktopApi }).gitnexusDesktop ?? fallbackDesktopApi;
|
||||
|
||||
const shellState: DesktopShellState = {
|
||||
...defaultDesktopState,
|
||||
|
|
@ -203,4 +204,4 @@ void desktopApi.getShellState().then((state) => {
|
|||
|
||||
desktopApi.onWindowStateChanged((state) => {
|
||||
applyShellState(state);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,4 +19,4 @@ body {
|
|||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@
|
|||
"path": "./tsconfig.renderer.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@
|
|||
"noEmit": true
|
||||
},
|
||||
"include": ["electron.vite.config.ts", "src/main/**/*.ts"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,4 +18,4 @@
|
|||
"types": ["vite/client"]
|
||||
},
|
||||
"include": ["src/renderer/src/main.tsx"]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue