Add native titlebar & fix app restart for AppImages

This commit is contained in:
Gelaechter 2023-05-24 17:35:04 +02:00 committed by Jeff
parent d055ae89e0
commit a878875f83
12 changed files with 82 additions and 23 deletions

View file

@ -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', () => {

View file

@ -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'};
}
`;

View file

@ -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');

View file

@ -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">

View file

@ -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}

View file

@ -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,

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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',

View file

@ -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}