Add native titlebar & fix app restart for AppImages
This commit is contained in:
parent
d055ae89e0
commit
a878875f83
12 changed files with 82 additions and 23 deletions
|
@ -183,8 +183,12 @@ const createWindow = async () => {
|
|||
await installExtensions();
|
||||
}
|
||||
|
||||
const nativeFrame = store.get('window_window_bar_style') === 'linux';
|
||||
store.set('window_has_frame', nativeFrame);
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
frame: false,
|
||||
autoHideMenuBar: nativeFrame,
|
||||
frame: nativeFrame,
|
||||
height: 900,
|
||||
icon: getAssetPath('icon.png'),
|
||||
minHeight: 600,
|
||||
|
@ -229,8 +233,18 @@ const createWindow = async () => {
|
|||
});
|
||||
|
||||
ipcMain.on('app-restart', () => {
|
||||
app.relaunch();
|
||||
app.exit(0);
|
||||
// Fix for .AppImage
|
||||
if (process.env.APPIMAGE) {
|
||||
app.exit();
|
||||
app.relaunch({
|
||||
args: process.argv.slice(1).concat(['--appimage-extract-and-run']),
|
||||
execPath: process.env.APPIMAGE,
|
||||
});
|
||||
app.exit(0);
|
||||
} else {
|
||||
app.relaunch();
|
||||
app.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('global-media-keys-enable', () => {
|
||||
|
|
|
@ -34,12 +34,16 @@ const StyledNativeScrollArea = styled.div<{ scrollBarOffset?: string; windowBarS
|
|||
|
||||
&::-webkit-scrollbar-track {
|
||||
margin-top: ${(props) =>
|
||||
props.windowBarStyle !== Platform.WEB ? '0px' : props.scrollBarOffset || '65px'};
|
||||
props.windowBarStyle === Platform.WINDOWS || props.windowBarStyle === Platform.MACOS
|
||||
? '0px'
|
||||
: props.scrollBarOffset || '65px'};
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
margin-top: ${(props) =>
|
||||
props.windowBarStyle !== Platform.WEB ? '0px' : props.scrollBarOffset || '65px'};
|
||||
props.windowBarStyle === Platform.WINDOWS || props.windowBarStyle === Platform.MACOS
|
||||
? '0px'
|
||||
: props.scrollBarOffset || '65px'};
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@ export const useFixedTableHeader = () => {
|
|||
const { windowBarStyle } = useWindowSettings();
|
||||
|
||||
const isNotPastTableIntersection = useInView(intersectRef, {
|
||||
margin: windowBarStyle === Platform.WEB ? '-68px 0px 0px 0px' : '-98px 0px 0px 0px',
|
||||
margin:
|
||||
windowBarStyle === Platform.WEB || windowBarStyle === Platform.LINUX
|
||||
? '-68px 0px 0px 0px'
|
||||
: '-98px 0px 0px 0px',
|
||||
});
|
||||
|
||||
const tableInView = useInView(tableContainerRef, {
|
||||
|
@ -21,13 +24,13 @@ export const useFixedTableHeader = () => {
|
|||
const root = document.querySelector('main .ag-root');
|
||||
|
||||
if (isNotPastTableIntersection || !tableInView) {
|
||||
if (windowBarStyle !== Platform.WEB) {
|
||||
if (windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS) {
|
||||
header?.classList.remove('window-frame');
|
||||
}
|
||||
header?.classList.remove('ag-header-fixed');
|
||||
root?.classList.remove('ag-header-fixed-margin');
|
||||
} else {
|
||||
if (windowBarStyle !== Platform.WEB) {
|
||||
if (windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS) {
|
||||
header?.classList.add('window-frame');
|
||||
}
|
||||
header?.classList.add('ag-header-fixed');
|
||||
|
|
|
@ -138,7 +138,9 @@ const HomeRoute = () => {
|
|||
<Box
|
||||
ref={cq.ref}
|
||||
mb="5rem"
|
||||
pt={windowBarStyle === Platform.WEB ? '5rem' : '3rem'}
|
||||
pt={
|
||||
windowBarStyle === Platform.WEB || windowBarStyle === Platform.LINUX ? '5rem' : '3rem'
|
||||
}
|
||||
px="2rem"
|
||||
>
|
||||
<Stack spacing="lg">
|
||||
|
|
|
@ -13,16 +13,17 @@ export const SidebarPlayQueue = () => {
|
|||
const queueRef = useRef<{ grid: AgGridReactType<Song> } | null>(null);
|
||||
const { windowBarStyle } = useWindowSettings();
|
||||
|
||||
const webOrNative = windowBarStyle === Platform.WEB || windowBarStyle === Platform.LINUX;
|
||||
return (
|
||||
<VirtualGridContainer>
|
||||
{windowBarStyle === Platform.WEB && (
|
||||
<Stack mr={windowBarStyle === Platform.WEB ? '130px' : undefined}>
|
||||
{webOrNative && (
|
||||
<Stack mr={webOrNative ? '130px' : undefined}>
|
||||
<PageHeader backgroundColor="var(--titlebar-bg)" />
|
||||
</Stack>
|
||||
)}
|
||||
<Paper
|
||||
display={windowBarStyle !== Platform.WEB ? 'flex' : undefined}
|
||||
h={windowBarStyle !== Platform.WEB ? '65px' : undefined}
|
||||
display={!webOrNative ? 'flex' : undefined}
|
||||
h={!webOrNative ? '65px' : undefined}
|
||||
>
|
||||
<PlayQueueListControls
|
||||
tableRef={queueRef}
|
||||
|
|
|
@ -129,7 +129,10 @@ const containerVariants: Variants = {
|
|||
closed: (custom) => {
|
||||
const { windowBarStyle } = custom;
|
||||
return {
|
||||
height: windowBarStyle !== Platform.WEB ? 'calc(100vh - 120px)' : 'calc(100vh - 90px)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS
|
||||
? 'calc(100vh - 120px)'
|
||||
: 'calc(100vh - 90px)',
|
||||
position: 'absolute',
|
||||
top: '100vh',
|
||||
transition: {
|
||||
|
@ -144,7 +147,10 @@ const containerVariants: Variants = {
|
|||
const { dynamicBackground, background, windowBarStyle } = custom;
|
||||
return {
|
||||
background: dynamicBackground ? background : 'var(--main-bg)',
|
||||
height: windowBarStyle !== Platform.WEB ? 'calc(100vh - 120px)' : 'calc(100vh - 90px)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS
|
||||
? 'calc(100vh - 120px)'
|
||||
: 'calc(100vh - 90px)',
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
|
|
|
@ -5,12 +5,13 @@ import {
|
|||
SettingsSection,
|
||||
SettingOption,
|
||||
} from '/@/renderer/features/settings/components/settings-section';
|
||||
import { Select, Switch } from '/@/renderer/components';
|
||||
import { Select, Switch, toast } from '/@/renderer/components';
|
||||
|
||||
const WINDOW_BAR_OPTIONS = [
|
||||
{ label: 'Web (hidden)', value: Platform.WEB },
|
||||
{ label: 'Windows', value: Platform.WINDOWS },
|
||||
{ label: 'macOS', value: Platform.MACOS },
|
||||
{ label: 'Native', value: Platform.LINUX },
|
||||
];
|
||||
|
||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||
|
@ -28,6 +29,26 @@ export const WindowSettings = () => {
|
|||
value={settings.windowBarStyle}
|
||||
onChange={(e) => {
|
||||
if (!e) return;
|
||||
|
||||
// warn that a restart is required
|
||||
if (
|
||||
(localSettings?.get('window_has_frame') && e !== Platform.LINUX) ||
|
||||
(!localSettings?.get('window_has_frame') && e === Platform.LINUX)
|
||||
) {
|
||||
toast.info({
|
||||
autoClose: false,
|
||||
id: 'restart-toast',
|
||||
message: 'Restart to apply changes... close the notification to restart Feishin',
|
||||
onClose: () => {
|
||||
window.electron.ipc.send('app-restart');
|
||||
},
|
||||
title: 'Restart required',
|
||||
});
|
||||
} else {
|
||||
toast.update({ autoClose: 0, id: 'restart-toast', message: '', onClose: () => {} }); // clean old toasts
|
||||
}
|
||||
|
||||
localSettings?.set('window_window_bar_style', e as Platform);
|
||||
setSettings({
|
||||
window: {
|
||||
...settings,
|
||||
|
|
|
@ -34,7 +34,7 @@ const SidebarContainer = styled(motion.div)<{ windowBarStyle: Platform }>`
|
|||
flex-direction: column;
|
||||
height: 100%;
|
||||
max-height: ${(props) =>
|
||||
props.windowBarStyle === Platform.WEB
|
||||
props.windowBarStyle === Platform.WEB || props.windowBarStyle === Platform.LINUX
|
||||
? 'calc(100vh - 149px)'
|
||||
: 'calc(100vh - 119px)'}; // Playerbar (90px), titlebar (65px), windowbar (30px)
|
||||
user-select: none;
|
||||
|
|
|
@ -45,7 +45,7 @@ import { useWindowSettings } from '../../../store/settings.store';
|
|||
const SidebarContainer = styled.div<{ windowBarStyle: Platform }>`
|
||||
height: 100%;
|
||||
max-height: ${(props) =>
|
||||
props.windowBarStyle === Platform.WEB
|
||||
props.windowBarStyle === Platform.WEB || props.windowBarStyle === Platform.LINUX
|
||||
? 'calc(100vh - 149px)'
|
||||
: 'calc(100vh - 179px)'}; // Playerbar (90px), titlebar (65px), windowbar (30px)
|
||||
user-select: none;
|
||||
|
|
|
@ -29,7 +29,7 @@ const Layout = styled.div<{ windowBarStyle: Platform }>`
|
|||
'main-content'
|
||||
'player';
|
||||
grid-template-rows: ${(props) =>
|
||||
props.windowBarStyle !== Platform.WEB
|
||||
props.windowBarStyle === Platform.WINDOWS || props.windowBarStyle === Platform.MACOS
|
||||
? '30px calc(100vh - 120px) 90px'
|
||||
: '0px calc(100vh - 90px) 90px'};
|
||||
grid-template-columns: 1fr;
|
||||
|
|
|
@ -104,7 +104,10 @@ const QueueDrawerArea = styled(motion.div)`
|
|||
|
||||
const queueDrawerVariants: Variants = {
|
||||
closed: (windowBarStyle) => ({
|
||||
height: windowBarStyle !== Platform.WEB ? 'calc(100vh - 205px)' : 'calc(100vh - 175px)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: '75px',
|
||||
|
@ -117,7 +120,10 @@ const queueDrawerVariants: Variants = {
|
|||
}),
|
||||
open: (windowBarStyle) => ({
|
||||
boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)',
|
||||
height: windowBarStyle !== Platform.WEB ? 'calc(100vh - 205px)' : 'calc(100vh - 175px)',
|
||||
height:
|
||||
windowBarStyle === Platform.WINDOWS || Platform.MACOS
|
||||
? 'calc(100vh - 205px)'
|
||||
: 'calc(100vh - 175px)',
|
||||
position: 'absolute',
|
||||
right: '20px',
|
||||
top: '75px',
|
||||
|
|
|
@ -219,6 +219,7 @@ export const WindowBar = () => {
|
|||
const statusString = playerStatus === PlayerStatus.PAUSED ? '(Paused) ' : '';
|
||||
const queueString = length ? `(${index + 1} / ${length}) ` : '';
|
||||
const title = length ? `${statusString}${queueString}${currentSong?.name}` : 'Feishin';
|
||||
document.title = title;
|
||||
|
||||
const [max, setMax] = useState(false);
|
||||
|
||||
|
@ -237,12 +238,13 @@ export const WindowBar = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
{windowBarStyle === Platform.WINDOWS ? (
|
||||
{windowBarStyle === Platform.WINDOWS && (
|
||||
<WindowsControls
|
||||
controls={{ handleClose, handleMaximize, handleMinimize }}
|
||||
title={title}
|
||||
/>
|
||||
) : (
|
||||
)}
|
||||
{windowBarStyle === Platform.MACOS && (
|
||||
<MacOsControls
|
||||
controls={{ handleClose, handleMaximize, handleMinimize }}
|
||||
title={title}
|
||||
|
|
Reference in a new issue