mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
native menu, fullscreen refactor
This commit is contained in:
parent
9267ca326f
commit
7b8c0be044
@ -14,9 +14,7 @@ const BrowserWindow = electron.BrowserWindow;
|
||||
const path = require('path');
|
||||
const url = require('url');
|
||||
const mainMenuDefinition = require('./mainMenuDefinition');
|
||||
|
||||
let useNativeMenu = true;
|
||||
let useNativeMenuSpecified = null;
|
||||
const { settings } = require('cluster');
|
||||
|
||||
// require('@electron/remote/main').initialize();
|
||||
|
||||
@ -104,9 +102,6 @@ ipcMain.on('set-title', async (event, arg) => {
|
||||
ipcMain.on('open-link', async (event, arg) => {
|
||||
electron.shell.openExternal(arg);
|
||||
});
|
||||
ipcMain.on('set-use-native-menu', async (event, arg) => {
|
||||
useNativeMenuSpecified = arg;
|
||||
});
|
||||
ipcMain.on('window-action', async (event, arg) => {
|
||||
switch (arg) {
|
||||
case 'minimize':
|
||||
@ -122,8 +117,11 @@ ipcMain.on('window-action', async (event, arg) => {
|
||||
case 'close':
|
||||
mainWindow.close();
|
||||
break;
|
||||
case 'fullscreen':
|
||||
mainWindow.setFullScreen(!mainWindow.isFullScreen());
|
||||
case 'fullscreen-on':
|
||||
mainWindow.setFullScreen(true);
|
||||
break;
|
||||
case 'fullscreen-off':
|
||||
mainWindow.setFullScreen(false);
|
||||
break;
|
||||
case 'devtools':
|
||||
mainWindow.webContents.toggleDevTools();
|
||||
@ -157,21 +155,31 @@ ipcMain.handle('showItemInFolder', async (event, path) => {
|
||||
ipcMain.handle('openExternal', async (event, url) => {
|
||||
electron.shell.openExternal(url);
|
||||
});
|
||||
ipcMain.handle('useNativeMenu', async () => {
|
||||
return useNativeMenu;
|
||||
});
|
||||
|
||||
function fillMissingSettings(value) {
|
||||
const res = {
|
||||
...value,
|
||||
};
|
||||
if (value['app.useNativeMenu'] !== true && value['app.useNativeMenu'] !== false) {
|
||||
res['app.useNativeMenu'] = os.platform() == 'darwin' ? true : false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
let settingsJson = {};
|
||||
try {
|
||||
const datadir = path.join(os.homedir(), 'dbgate-data');
|
||||
settingsJson = fillMissingSettings(
|
||||
JSON.parse(fs.readFileSync(path.join(datadir, 'settings.json'), { encoding: 'utf-8' }))
|
||||
);
|
||||
} catch (err) {
|
||||
console.log('Error loading settings.json:', err.message);
|
||||
settingsJson = fillMissingSettings({});
|
||||
}
|
||||
|
||||
const bounds = initialConfig['winBounds'];
|
||||
useNativeMenu = os.platform() == 'darwin' ? true : false;
|
||||
if (initialConfig['useNativeMenu'] === true) {
|
||||
useNativeMenu = true;
|
||||
useNativeMenuSpecified = true;
|
||||
}
|
||||
if (initialConfig['useNativeMenu'] === false) {
|
||||
useNativeMenu = false;
|
||||
useNativeMenuSpecified = false;
|
||||
}
|
||||
useNativeMenu = settingsJson['app.useNativeMenu'];
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
@ -192,17 +200,14 @@ function createWindow() {
|
||||
if (initialConfig['winIsMaximized']) {
|
||||
mainWindow.maximize();
|
||||
}
|
||||
if (initialConfig['winIsFullscreen']) {
|
||||
if (settingsJson['app.fullscreen']) {
|
||||
mainWindow.setFullScreen(true);
|
||||
}
|
||||
|
||||
mainMenu = buildMenu();
|
||||
mainWindow.setMenu(mainMenu);
|
||||
|
||||
async function loadMainWindow() {
|
||||
const settings = await main.configController.getSettings();
|
||||
console.log(settings);
|
||||
|
||||
function loadMainWindow() {
|
||||
const startUrl =
|
||||
process.env.ELECTRON_START_URL ||
|
||||
url.format({
|
||||
@ -217,8 +222,6 @@ function createWindow() {
|
||||
JSON.stringify({
|
||||
winBounds: mainWindow.getBounds(),
|
||||
winIsMaximized: mainWindow.isMaximized(),
|
||||
useNativeMenu: useNativeMenuSpecified,
|
||||
winIsFullscreen: mainWindow.isFullScreen(),
|
||||
}),
|
||||
'utf-8'
|
||||
);
|
||||
@ -230,6 +233,7 @@ function createWindow() {
|
||||
if (os.platform() == 'linux') {
|
||||
mainWindow.setIcon(path.resolve(__dirname, '../icon.png'));
|
||||
}
|
||||
// mainWindow.webContents.toggleDevTools();
|
||||
}
|
||||
|
||||
const apiPackage = path.join(
|
||||
|
@ -1,4 +1,5 @@
|
||||
const fs = require('fs-extra');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const axios = require('axios');
|
||||
const { datadir } = require('../utility/directories');
|
||||
@ -44,12 +45,24 @@ module.exports = {
|
||||
getSettings_meta: true,
|
||||
async getSettings() {
|
||||
try {
|
||||
return JSON.parse(await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' }));
|
||||
return this.fillMissingSettings(
|
||||
JSON.parse(await fs.readFile(path.join(datadir(), 'settings.json'), { encoding: 'utf-8' }))
|
||||
);
|
||||
} catch (err) {
|
||||
return {};
|
||||
return this.fillMissingSettings({});
|
||||
}
|
||||
},
|
||||
|
||||
fillMissingSettings(value) {
|
||||
const res = {
|
||||
...value,
|
||||
};
|
||||
if (value['app.useNativeMenu'] !== true && value['app.useNativeMenu'] !== false) {
|
||||
res['app.useNativeMenu'] = os.platform() == 'darwin' ? true : false;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
updateSettings_meta: true,
|
||||
async updateSettings(values) {
|
||||
if (!hasPermission(`settings/change`)) return false;
|
||||
|
@ -15,9 +15,8 @@
|
||||
import { subscribeConnectionPingers } from './utility/connectionsPinger';
|
||||
import { subscribePermissionCompiler } from './utility/hasPermission';
|
||||
import { apiCall } from './utility/api';
|
||||
import { getConfig, getUsedApps } from './utility/metadataLoaders';
|
||||
import { getConfig, getSettings, getUsedApps } from './utility/metadataLoaders';
|
||||
import AppTitleProvider from './utility/AppTitleProvider.svelte';
|
||||
import { initTitleBarVisibility } from './utility/common';
|
||||
|
||||
let loadedApi = false;
|
||||
|
||||
@ -27,13 +26,11 @@
|
||||
// return;
|
||||
// }
|
||||
|
||||
await initTitleBarVisibility();
|
||||
|
||||
try {
|
||||
// console.log('************** LOADING API');
|
||||
|
||||
const settings = await apiCall('config/get-settings');
|
||||
const connections = await apiCall('connections/list');
|
||||
const settings = await getSettings();
|
||||
const config = await getConfig();
|
||||
const apps = await getUsedApps();
|
||||
loadedApi = settings && connections && config && apps;
|
||||
|
@ -9,6 +9,7 @@
|
||||
openedSnackbars,
|
||||
selectedWidget,
|
||||
visibleCommandPalette,
|
||||
visibleTitleBar,
|
||||
visibleToolbar,
|
||||
} from './stores';
|
||||
import TabsPanel from './widgets/TabsPanel.svelte';
|
||||
@ -23,8 +24,6 @@
|
||||
import DragAndDropFileTarget from './DragAndDropFileTarget.svelte';
|
||||
import dragDropFileTarget from './utility/dragDropFileTarget';
|
||||
import TitleBar from './widgets/TitleBar.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { getTitleBarVisibility } from './utility/common';
|
||||
|
||||
$: currentThemeType = $currentThemeDefinition?.themeType == 'dark' ? 'theme-type-dark' : 'theme-type-light';
|
||||
|
||||
@ -42,7 +41,7 @@
|
||||
use:dragDropFileTarget
|
||||
on:contextmenu={e => e.preventDefault()}
|
||||
>
|
||||
{#if getTitleBarVisibility()}
|
||||
{#if $visibleTitleBar}
|
||||
<div class="titlebar">
|
||||
<TitleBar />
|
||||
</div>
|
||||
|
@ -27,6 +27,7 @@ import { showSnackbarSuccess } from '../utility/snackbar';
|
||||
import { apiCall } from '../utility/api';
|
||||
import runCommand from './runCommand';
|
||||
import { openWebLink } from '../utility/exportElectronFile';
|
||||
import { getSettings } from '../utility/metadataLoaders';
|
||||
|
||||
function themeCommand(theme: ThemeDefinition) {
|
||||
return {
|
||||
@ -596,7 +597,13 @@ registerCommand({
|
||||
name: 'Toggle full screen',
|
||||
keyText: 'F11',
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'fullscreen'),
|
||||
onClick: async () => {
|
||||
const settings = await getSettings();
|
||||
const value = !settings['app.fullscreen'];
|
||||
apiCall('config/update-settings', { 'app.fullscreen': value });
|
||||
if (value) getElectron().send('window-action', 'fullscreen-on');
|
||||
else getElectron().send('window-action', 'fullscreen-off');
|
||||
},
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
|
@ -1,23 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { getFormContext } from './FormProviderCore.svelte';
|
||||
import SettingsCheckboxFieldRaw from './SettingsCheckboxFieldRaw.svelte';
|
||||
|
||||
export let label;
|
||||
export let name;
|
||||
export let disabled = false;
|
||||
export let templateProps = {};
|
||||
|
||||
const { template, setFieldValue, values } = getFormContext();
|
||||
</script>
|
||||
|
||||
<svelte:component
|
||||
this={template}
|
||||
on:change
|
||||
type="checkbox"
|
||||
{label}
|
||||
{disabled}
|
||||
{...templateProps}
|
||||
labelProps={disabled ? { disabled: true } : { onClick: () => setFieldValue(name, !$values[name]) }}
|
||||
>
|
||||
<SettingsCheckboxFieldRaw {name} {...$$restProps} {disabled} />
|
||||
</svelte:component>
|
@ -1,17 +0,0 @@
|
||||
<script lang="ts">
|
||||
import CheckboxField from './CheckboxField.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import _ from 'lodash';
|
||||
import { useSettings } from '../utility/metadataLoaders';
|
||||
|
||||
export let name;
|
||||
export let defaultValue;
|
||||
|
||||
const settings = useSettings();
|
||||
|
||||
function handleChange(e) {
|
||||
apiCall('config/update-settings', { [name]: e.target['checked'] });
|
||||
}
|
||||
</script>
|
||||
|
||||
<CheckboxField {...$$restProps} checked={($settings || {})[name] ?? defaultValue} on:change={handleChange} on:change />
|
@ -1,15 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { getFormContext } from './FormProviderCore.svelte';
|
||||
import SettingsTextFieldRaw from './SettingsTextFieldRaw.svelte';
|
||||
|
||||
export let label;
|
||||
export let name;
|
||||
export let templateProps = {};
|
||||
export let focused = false;
|
||||
|
||||
const { template } = getFormContext();
|
||||
</script>
|
||||
|
||||
<svelte:component this={template} type="text" {label} {...templateProps}>
|
||||
<SettingsTextFieldRaw {name} {...$$restProps} {focused} />
|
||||
</svelte:component>
|
@ -1,18 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { apiCall } from '../utility/api';
|
||||
|
||||
import { useSettings } from '../utility/metadataLoaders';
|
||||
|
||||
import TextField from './TextField.svelte';
|
||||
|
||||
export let name;
|
||||
export let defaultValue;
|
||||
|
||||
const settings = useSettings();
|
||||
|
||||
function handleChange(e) {
|
||||
apiCall('config/update-settings', { [name]: e.target['value'] });
|
||||
}
|
||||
</script>
|
||||
|
||||
<TextField {...$$restProps} value={($settings || {})[name] ?? defaultValue} on:input={handleChange} />
|
@ -2,40 +2,16 @@
|
||||
import _ from 'lodash';
|
||||
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||
|
||||
import FormButton from '../forms/FormButton.svelte';
|
||||
import FormCheckboxField from '../forms/FormCheckboxField.svelte';
|
||||
import FormProvider from '../forms/FormProvider.svelte';
|
||||
|
||||
import FormProvider from '../forms/FormProvider.svelte';
|
||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import FormValues from '../forms/FormValues.svelte';
|
||||
import SettingsCheckboxField from '../forms/SettingsCheckboxField.svelte';
|
||||
import SettingsFormProvider from '../forms/SettingsFormProvider.svelte';
|
||||
import SettingsTextField from '../forms/SettingsTextField.svelte';
|
||||
|
||||
import ModalBase from '../modals/ModalBase.svelte';
|
||||
import { closeCurrentModal } from '../modals/modalTools';
|
||||
import { getCurrentSettings, getVisibleToolbar, getZoomKoef, visibleToolbar, zoomKoef } from '../stores';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { getTitleBarVisibility } from '../utility/common';
|
||||
import getElectron from '../utility/getElectron';
|
||||
import { showSnackbarInfo } from '../utility/snackbar';
|
||||
|
||||
// function handleOk(e) {
|
||||
// apiCall(
|
||||
// 'config/update-settings',
|
||||
// _.omitBy(e.detail, (v, k) => k.startsWith(':'))
|
||||
// );
|
||||
// visibleToolbar.set(!!e.detail[':visibleToolbar']);
|
||||
// if (electron && !getTitleBarVisibility() != !!e.detail[':useNativeMenu']) {
|
||||
// electron.send('set-use-native-menu', !!e.detail[':useNativeMenu']);
|
||||
// showSnackbarInfo('Native menu settings will be applied after app restart');
|
||||
// }
|
||||
// closeCurrentModal();
|
||||
// }
|
||||
|
||||
const electron = getElectron();
|
||||
</script>
|
||||
|
||||
|
@ -76,9 +76,25 @@ export const currentThemeDefinition = derived([currentTheme, extensions], ([$cur
|
||||
$extensions.themes.find(x => x.themeClassName == $currentTheme)
|
||||
);
|
||||
|
||||
export const visibleTitleBar = derived(useSettings(), $settings => {
|
||||
const electron = getElectron();
|
||||
if (!electron) return false;
|
||||
// console.log('visibleTitleBar:settings', $settings);
|
||||
if (!$settings) return false;
|
||||
return !$settings['app.fullscreen'] && !$settings['app.useNativeMenu'];
|
||||
});
|
||||
|
||||
export const visibleHamburgerMenuWidget = derived(useSettings(), $settings => {
|
||||
const electron = getElectron();
|
||||
if (!electron) return true;
|
||||
if (!$settings) return false;
|
||||
return !!$settings['app.fullscreen'];
|
||||
});
|
||||
|
||||
subscribeCssVariable(selectedWidget, x => (x ? 1 : 0), '--dim-visible-left-panel');
|
||||
// subscribeCssVariable(visibleToolbar, x => (x ? 1 : 0), '--dim-visible-toolbar');
|
||||
subscribeCssVariable(leftPanelWidth, x => `${x}px`, '--dim-left-panel-width');
|
||||
subscribeCssVariable(visibleTitleBar, x => (x ? 1 : 0), '--dim-visible-titlebar');
|
||||
|
||||
let activeTabIdValue = null;
|
||||
activeTabId.subscribe(value => {
|
||||
|
@ -39,24 +39,3 @@ export async function asyncFilter(arr, predicate) {
|
||||
|
||||
return arr.filter((_v, index) => results[index]);
|
||||
}
|
||||
|
||||
async function computeTitleBarVisibility() {
|
||||
const electron = getElectron();
|
||||
if (!electron) {
|
||||
return false;
|
||||
}
|
||||
if (await electron.useNativeMenu()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
let titleBarVisibility = false;
|
||||
export async function initTitleBarVisibility() {
|
||||
titleBarVisibility = await computeTitleBarVisibility();
|
||||
document.documentElement.style.setProperty('--dim-visible-titlebar', titleBarVisibility ? '1' : '0');
|
||||
}
|
||||
|
||||
export function getTitleBarVisibility() {
|
||||
return titleBarVisibility;
|
||||
}
|
||||
|
@ -26,11 +26,6 @@ class ElectronApi {
|
||||
await this.ipcRenderer.invoke('openExternal', url);
|
||||
}
|
||||
|
||||
async useNativeMenu() {
|
||||
const res = await this.ipcRenderer.invoke('useNativeMenu');
|
||||
return res;
|
||||
}
|
||||
|
||||
async invoke(route, args) {
|
||||
const res = await this.ipcRenderer.invoke(route, args);
|
||||
return res;
|
||||
|
@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { currentDropDownMenu, selectedWidget, visibleCommandPalette } from '../stores';
|
||||
import { getTitleBarVisibility } from '../utility/common';
|
||||
import { currentDropDownMenu, selectedWidget, visibleCommandPalette, visibleHamburgerMenuWidget } from '../stores';
|
||||
import mainMenuDefinition from '../../../../app/src/mainMenuDefinition';
|
||||
|
||||
let domSettings;
|
||||
@ -81,7 +80,7 @@
|
||||
</script>
|
||||
|
||||
<div class="main">
|
||||
{#if !getTitleBarVisibility()}
|
||||
{#if $visibleHamburgerMenuWidget}
|
||||
<div class="wrapper mb-3" on:click={handleMainMenu} bind:this={domMainMenu}>
|
||||
<FontIcon icon="icon menu" />
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user