Skip to content

Commit

Permalink
fix: handle dynamic gauzy api host from desktop config
Browse files Browse the repository at this point in the history
  • Loading branch information
nyomansutralia-jubelio committed Nov 24, 2024
1 parent b80062b commit 6296acf
Show file tree
Hide file tree
Showing 17 changed files with 268 additions and 89 deletions.
64 changes: 64 additions & 0 deletions .scripts/configure.electron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as fs from 'fs';
import * as path from 'path';
import { hideBin } from 'yargs/helpers';
import yargs from 'yargs';

const argv: any = yargs(hideBin(process.argv)).argv;

function modifiedNextServer() {
const filePath = path.resolve(__dirname, '../apps/server-web/release/app/dist/standalone/apps/web/server.js');

let fileContent = fs.readFileSync(filePath, 'utf8');
const searchString = 'process.env.__NEXT_PRIVATE_STANDALONE_CONFIG';
const codeToInsert = `
nextConfig.serverRuntimeConfig = {
"GAUZY_API_SERVER_URL": process.env.GAUZY_API_SERVER_URL,
"NEXT_PUBLIC_GAUZY_API_SERVER_URL": process.env.NEXT_PUBLIC_GAUZY_API_SERVER_URL
}
`;

let lines = fileContent.split('\n');
const index = lines.findIndex((line) => line.includes(searchString));

if (index !== -1) {
lines.splice(index - 1, 0, codeToInsert);

fileContent = lines.join('\n');
fs.writeFileSync(filePath, fileContent, 'utf8');
console.log('Line of code successfully inserted.');
} else {
console.log(`The string "${searchString}" was not found in the file.`);
}
}

function modifiedWebConstant() {
const filePath = path.resolve(__dirname, '../apps/web/app/constants.ts');

let fileContent = fs.readFileSync(filePath, 'utf8');
const searchString = `export const IS_DESKTOP_APP = process.env.IS_DESKTOP_APP === 'true';`;
const codeToReplace = `export const IS_DESKTOP_APP = true;`;

fileContent = fileContent.replace(searchString, codeToReplace);

fs.writeFileSync(filePath, fileContent, 'utf8');
}

function revertWebConstant() {
const filePath = path.resolve(__dirname, '../apps/web/app/constants.ts');

let fileContent = fs.readFileSync(filePath, 'utf8');
const codeToReplace = `export const IS_DESKTOP_APP = process.env.IS_DESKTOP_APP === 'true';`;
const searchString = `export const IS_DESKTOP_APP = true;`;

fileContent = fileContent.replace(searchString, codeToReplace);

fs.writeFileSync(filePath, fileContent, 'utf8');
}


if (argv.type === 'server') {
modifiedNextServer();
revertWebConstant();
} else if (argv.type === 'constant') {
modifiedWebConstant();
}
2 changes: 1 addition & 1 deletion apps/server-web/src/main/helpers/interfaces/i-constant.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export type Channels = 'setting-page' | 'ipc-renderer' | 'language-set' | 'updater-page' | 'server-page' | 'theme-change' | 'current-theme';
export type Channels = 'setting-page' | 'ipc-renderer' | 'language-set' | 'updater-page' | 'server-page' | 'theme-change' | 'current-theme' | 'current-language';
12 changes: 12 additions & 0 deletions apps/server-web/src/main/helpers/replace-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,15 @@ export const replaceConfig = async (folderPath: string, envOptions: EnvOptions)
console.log('error on replacing file', error);
}
}

export const clearDesktopConfig = (folderPath: string) => {
const fileNames = ['desktop-server.body', 'desktop-server.meta'];
try {
// remove cached desktop server config
fileNames.forEach((file) => {
fs.unlinkSync(path.join(folderPath, file));
})
} catch (error) {
console.log('skip unlink file on not exists');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export class DesktopServerFactory {
if (!this.apiInstance && !!env) {
this.apiInstance = new WebService(path, env, win, signal, eventEmitter);
}
this.apiInstance.env = env;
return this.apiInstance;
}
}
10 changes: 3 additions & 7 deletions apps/server-web/src/main/helpers/services/web-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { EventEmitter } from 'stream';
export class WebService extends ServerTask {
constructor(
readonly path: string,
readonly env: any,
public env: any,
readonly window: BrowserWindow,
readonly signal: AbortSignal,
readonly eventEmitter: EventEmitter
Expand Down Expand Up @@ -38,11 +38,7 @@ export class WebService extends ServerTask {
}
}

private setApiConfig(): void {
// Object.assign(this.args, {
// API_HOST: '0.0.0.0',
// API_PORT: this.config.setting.PORT,
// API_BASE_URL: this.config.apiUrl
// });
public setApiConfig(): void {
Object.assign(this.args, {...this.env});
}
}
79 changes: 47 additions & 32 deletions apps/server-web/src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { mainBindings } from 'i18next-electron-fs-backend';
import i18nextMainBackend from '../configs/i18n.mainconfig';
import fs from 'fs';
import { WebServer, AppMenu, ServerConfig } from './helpers/interfaces';
import { replaceConfig } from './helpers';
import { clearDesktopConfig } from './helpers';
import Log from 'electron-log';
import MenuBuilder from './menu';
import { config } from '../configs/config';
Expand Down Expand Up @@ -210,11 +210,16 @@ const runServer = async () => {
console.log('Run the Server...');
try {
const envVal: ServerConfig | undefined = getEnvApi();
const folderPath = getWebDirPath();
await clearDesktopConfig(folderPath);

// Instantiate API and UI servers
await desktopServer.start(
{ api: serverPath },
envVal,
{
...envVal,
IS_DESKTOP_APP: true
},
undefined,
signal
);
Expand Down Expand Up @@ -254,19 +259,9 @@ const SendMessageToSettingWindow = (type: string, data: any) => {

const onInitApplication = () => {
// check and set default config
try {
LocalStore.setDefaultServerConfig();
createIntervalAutoUpdate()
trayMenuItems = trayMenuItems.length ? trayMenuItems : defaultTrayMenuItem(eventEmitter);
appMenuItems = appMenuItems.length ? appMenuItems : appMenu.defaultMenu();
tray = _initTray(trayMenuItems, getAssetPath('icons/icon.png'));
} catch (error) {
console.error('Failed to initialize application:', error);
dialog.showErrorBox('Initialization Error', 'Failed to initialize application');
}
const storeConfig:WebServer = LocalStore.getStore('config');
i18nextMainBackend.on('languageChanged', debounce((lng) => {
if (i18nextMainBackend.isInitialized) {

if (i18nextMainBackend.isInitialized && storeConfig.general?.setup) {
trayMenuItems = trayMenuItems.length ? trayMenuItems : defaultTrayMenuItem(eventEmitter);
updateTrayMenu('none', {}, eventEmitter, tray, trayMenuItems, i18nextMainBackend);
Menu.setApplicationMenu(appMenu.buildDefaultTemplate(appMenuItems, i18nextMainBackend))
Expand Down Expand Up @@ -433,21 +428,40 @@ const onInitApplication = () => {
eventEmitter.on(EventLists.SERVER_WINDOW_DEV, () => {
logWindow?.webContents.toggleDevTools();
})
}

eventEmitter.emit(EventLists.SERVER_WINDOW);
const initTrayMenu = () => {
try {
LocalStore.setDefaultServerConfig();
createIntervalAutoUpdate()
trayMenuItems = trayMenuItems.length ? trayMenuItems : defaultTrayMenuItem(eventEmitter);
appMenuItems = appMenuItems.length ? appMenuItems : appMenu.defaultMenu();
tray = _initTray(trayMenuItems, getAssetPath('icons/icon.png'));
} catch (error) {
console.error('Failed to initialize application:', error);
dialog.showErrorBox('Initialization Error', 'Failed to initialize application');
}
}

(async () => {
await app.whenReady()
const storeConfig:WebServer = LocalStore.getStore('config');
onInitApplication();
if (storeConfig?.general?.setup) {
onInitApplication();
initTrayMenu()
eventEmitter.emit(EventLists.SERVER_WINDOW);
} else {
if (!setupWindow) {
await createWindow('SETUP_WINDOW');
}
if (setupWindow) {
setupWindow?.show()
setupWindow?.show();
setupWindow?.
setupWindow?.webContents.once('did-finish-load', () => {
setTimeout(() => {
setupWindow?.webContents.send('languageSignal', storeConfig.general?.lang);
}, 50)
})
}
}
})()
Expand All @@ -461,27 +475,23 @@ ipcMain.on('message', async (event, arg) => {
event.reply('message', `${arg} World!`)
})

const getWebDirPath = () => {
const dirFiles = 'standalone/apps/web/.next/server/app/api';
const devDirFilesPath = path.join(__dirname, resourceDir.webServer, dirFiles);
const packDirFilesPath = path.join(process.resourcesPath, 'release', 'app', 'dist', dirFiles)
const diFilesPath = isPack ? packDirFilesPath : devDirFilesPath;
return diFilesPath;
}

ipcMain.on(IPC_TYPES.SETTING_PAGE, async (event, arg) => {
switch (arg.type) {
case SettingPageTypeMessage.saveSetting:
const existingConfig = getEnvApi();
LocalStore.updateConfigSetting({
server: arg.data
});
const dirFiles = 'standalone/apps/web/.next';
const devDirFilesPath = path.join(__dirname, resourceDir.webServer, dirFiles);
const packDirFilesPath = path.join(process.resourcesPath, 'release', 'app', 'dist', dirFiles)
const diFilesPath = isPack ? packDirFilesPath : devDirFilesPath;
await replaceConfig(
diFilesPath,
{
before: {
NEXT_PUBLIC_GAUZY_API_SERVER_URL: existingConfig?.NEXT_PUBLIC_GAUZY_API_SERVER_URL || config.NEXT_PUBLIC_GAUZY_API_SERVER_URL
},
after: {
NEXT_PUBLIC_GAUZY_API_SERVER_URL: arg.data.NEXT_PUBLIC_GAUZY_API_SERVER_URL || config.NEXT_PUBLIC_GAUZY_API_SERVER_URL
}
}
const diFilesPath = getWebDirPath();
await clearDesktopConfig(
diFilesPath
)
if (arg.isSetup) {
LocalStore.updateConfigSetting({
Expand Down Expand Up @@ -556,6 +566,11 @@ ipcMain.handle('current-theme', async () => {
return setting?.general?.theme;;
})

ipcMain.handle('current-language', async (): Promise<string> => {
const setting: WebServer = LocalStore.getStore('config');
return setting?.general?.lang || 'en';
})

const createIntervalAutoUpdate = () => {
if (intervalUpdate) {
clearInterval(intervalUpdate)
Expand Down
54 changes: 54 additions & 0 deletions apps/server-web/src/renderer/components/LanguageSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { useTranslation } from 'react-i18next';
import { SelectComponent } from './Select';
import { useState } from 'react';
import { ILanguages } from '../libs/interfaces';
import { SettingPageTypeMessage } from '../../main/helpers/constant';

type LanguageSelector = {
lang: string;
};
const LanguageSelector = ({ lang }: LanguageSelector) => {
const [langs] = useState<ILanguages[]>([
{
code: 'en',
label: 'English',
},
{
code: 'bg',
label: 'Bulgarian',
},
]);
const { t } = useTranslation();

const changeLanguage = (data: ILanguages) => {
window.electron.ipcRenderer.sendMessage('setting-page', {
type: SettingPageTypeMessage.langChange,
data: data.code,
});
setLng(data.code);
};

const [lng, setLng] = useState<string>(lang);

const language = langs.find((lg) => lg.code === lng) || {
code: 'en',
label: 'English',
};
return (
<SelectComponent
items={langs.map((i) => ({
value: i.code,
label: `LANGUAGES.${i.code}`,
}))}
title={t('FORM.LABELS.LANGUAGES')}
defaultValue={language.code}
onValueChange={(val) => {
changeLanguage({ code: val });
}}
disabled={false}
value={language.code}
/>
);
};

export default LanguageSelector;
21 changes: 2 additions & 19 deletions apps/server-web/src/renderer/components/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@ import { useTranslation } from 'react-i18next';
import { ISidebarComponent } from '../libs/interfaces';
import { SelectComponent } from './Select';
import { ThemeToggler } from './Toggler';
import LanguageSelector from './LanguageSelector';

export function SideBar({
children,
menus,
menuChange,
langs,
lang,
onLangChange,
}: ISidebarComponent) {
const { t } = useTranslation();
const language = langs.find((lg) => lg.code === lang) || {
code: 'en',
label: 'English',
};
return (
<div className="min-h-screen flex flex-col flex-auto flex-shrink-0 antialiased text-gray-800">
<div className="fixed flex flex-col top-0 left-0 w-1/4 h-full dark:bg-[#1c1e23] bg-gray-200">
Expand All @@ -43,19 +38,7 @@ export function SideBar({
</div>
<div className="flex items-center justify-center py-6 px-2">
<div className="flex flex-col w-6/8 mr-5">
<SelectComponent
items={langs.map((i) => ({
value: i.code,
label: `LANGUAGES.${i.code}`,
}))}
title={t('FORM.LABELS.LANGUAGES')}
defaultValue={language.code}
onValueChange={(lang) => {
onLangChange({ code: lang });
}}
disabled={false}
value={language.code}
/>
<LanguageSelector lang={lang} />
</div>

<div className="flex flex-col w-2/8">
Expand Down
2 changes: 0 additions & 2 deletions apps/server-web/src/renderer/libs/interfaces/i-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ type ISidebarComponent = {
children: string | JSX.Element | JSX.Element[];
menus: ISideMenu[];
menuChange: (key: string) => void;
langs: ILanguages[];
onLangChange: (lang: any) => void;
lang: string;
};

Expand Down
2 changes: 1 addition & 1 deletion apps/server-web/src/renderer/libs/interfaces/i-setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface IPopup {

interface ILanguages {
code: string;
label: string;
label?: string;
}

type IUpdateSetting = {
Expand Down
8 changes: 1 addition & 7 deletions apps/server-web/src/renderer/pages/Setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,7 @@ export function Setting() {
}, []);

return (
<SideBar
menus={menus}
menuChange={menuChange}
langs={langs}
lang={lng}
onLangChange={changeLanguage}
>
<SideBar menus={menus} menuChange={menuChange} lang={lng}>
<MenuComponent />
</SideBar>
);
Expand Down
Loading

0 comments on commit 6296acf

Please sign in to comment.