Skip to content

Commit 15eaa8c

Browse files
committed
feat: Edit playlist notes without editable (wip)
fix: Reimplement exit code for Electron
1 parent 9870d46 commit 15eaa8c

File tree

5 files changed

+77
-32
lines changed

5 files changed

+77
-32
lines changed

src/renderer/components/DisplayComponent.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ import { GameComponentDropdownSelectFieldProps, GameComponentInputFieldProps } f
22
import { InputField } from './InputField';
33
import { DropdownInputFieldMapped } from './DropdownInputField';
44

5-
export function GameComponentInputField({ header, onClick, multiline, text, placeholder, onChange, editable }: GameComponentInputFieldProps) {
5+
export function GameComponentInputField(props: GameComponentInputFieldProps) {
6+
const { header, onClick, multiline, text, placeholder, onChange, editable, HeaderComponent } = props;
7+
const headerRender = HeaderComponent ? <HeaderComponent {...props}/> : <p className='browse-right-sidebar__row-header-text'>{header}: </p>;
68
return (
79
<div className={`browse-right-sidebar__row ${!multiline ? 'browse-right-sidebar__row--one-line' : ''}`}>
8-
<p>{header}: </p>
10+
<div className='browse-right-sidebar__row-header'>
11+
{headerRender}
12+
</div>
913
<InputField
1014
text={text}
1115
placeholder={placeholder}

src/renderer/components/GameComponents.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ModelUtils } from '@shared/game/util';
22
import { deepCopy, generateTagFilterGroup } from '@shared/Util';
33
import { AdditionalApp, Game, Platform, Tag, TagSuggestion } from 'flashpoint-launcher';
4-
import { GameComponentProps } from 'flashpoint-launcher-renderer';
4+
import { GameComponentInputFieldProps, GameComponentProps } from 'flashpoint-launcher-renderer';
55
import { GameComponentInputField } from './DisplayComponent';
66
import { DropdownInputField, DropdownInputFieldMapped } from './DropdownInputField';
77
import { RightBrowseSidebarAddApp } from './RightBrowseSidebarAddApp';
@@ -333,7 +333,26 @@ export function GameComponentAddApps(props: GameComponentProps) {
333333

334334
export function GameComponentPlaylistNotes(props: GameComponentProps) {
335335
const { playlistGame, updatePlaylistNotes } = props;
336+
const upperEditable = props.editable;
336337
const lang = useContext(LangContext);
338+
const [editableOverride, setEditableOverride] = useState(false);
339+
const editable = editableOverride || upperEditable;
340+
console.log(upperEditable);
341+
342+
const HeaderComponent = (props: GameComponentInputFieldProps) => {
343+
return (
344+
<>
345+
<p className='browse-right-sidebar__row-header-text'>{props.header}: </p>
346+
{!upperEditable && (
347+
<>
348+
<div onClick={() => setEditableOverride(!editableOverride)}>
349+
<OpenIcon icon={editable ? 'check' : 'pencil'}/>
350+
</div>
351+
</>
352+
)}
353+
</>
354+
);
355+
};
337356

338357
if (playlistGame) {
339358
return (
@@ -343,7 +362,9 @@ export function GameComponentPlaylistNotes(props: GameComponentProps) {
343362
placeholder={lang.browse.noPlaylistNotes}
344363
multiline={true}
345364
onChange={(value) => updatePlaylistNotes(value)}
346-
{...props} />
365+
{...props}
366+
editable={editable}
367+
HeaderComponent={HeaderComponent} />
347368
);
348369
} else {
349370
return (<></>);

src/renderer/components/app.tsx

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -647,35 +647,47 @@ function initApp(dispatch: AppDispatch) {
647647
};
648648

649649
// Load FPFSS user info and check that profile works
650-
(() => {
651-
const userBase64 = localStorage.getItem('fpfss_user');
652-
if (userBase64) {
653-
try {
654-
const user = JSON.parse(Buffer.from(userBase64, 'base64').toString('utf-8')) as FpfssUser;
655-
// Test profile uri
656-
const profileUrl = `${window.Shared.initialPreferences.fpfssBaseUrl}/api/profile`;
657-
axios.get(profileUrl, {
658-
headers: {
659-
'Authorization': `Bearer ${user.accessToken}`
660-
}
661-
})
662-
.then((res) => {
663-
// Success, use most recent info and save to storage and state
664-
user.username = res.data['Username'];
665-
user.avatarUrl = res.data['AvatarURL'];
666-
user.roles = res.data['Roles'];
667-
dispatch(setFpfssUser(user));
668-
})
669-
.catch(() => {
670-
// Failed auth
671-
localStorage.removeItem('fpfss_user');
672-
});
673-
} catch (err) {
674-
log.error('Launcher', 'Fpfss saved auth was invalid, clearing...');
650+
const userBase64 = localStorage.getItem('fpfss_user');
651+
if (userBase64) {
652+
try {
653+
const user = JSON.parse(Buffer.from(userBase64, 'base64').toString('utf-8')) as FpfssUser;
654+
// Test profile uri
655+
const profileUrl = `${window.Shared.initialPreferences.fpfssBaseUrl}/api/profile`;
656+
axios.get(profileUrl, {
657+
headers: {
658+
'Authorization': `Bearer ${user.accessToken}`
659+
}
660+
})
661+
.then((res) => {
662+
// Success, use most recent info and save to storage and state
663+
user.username = res.data['Username'];
664+
user.avatarUrl = res.data['AvatarURL'];
665+
user.roles = res.data['Roles'];
666+
dispatch(setFpfssUser(user));
667+
})
668+
.catch(() => {
669+
// Failed auth
675670
localStorage.removeItem('fpfss_user');
676-
}
671+
});
672+
} catch (err) {
673+
log.error('Launcher', 'Fpfss saved auth was invalid, clearing...');
674+
localStorage.removeItem('fpfss_user');
677675
}
678-
})();
676+
}
677+
678+
if (window.electronAPI !== undefined) {
679+
// Only exit after window closure if we're running under Electron
680+
window.onbeforeunload = (event: BeforeUnloadEvent) => {
681+
event.stopPropagation();
682+
setTimeout(() => {
683+
window.Shared.back.allowDeath();
684+
window.Shared.back.request(BackIn.QUIT)
685+
.finally(() => {
686+
window.close();
687+
});
688+
}, 100);
689+
};
690+
}
679691

680692
registerWebsocketListeners(dispatch);
681693
}

static/window/styles/core.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1707,10 +1707,17 @@ body {
17071707
font-weight: bold;
17081708
font-size: 1.05em;
17091709
}
1710-
.browse-right-sidebar__row p {
1710+
.browse-right-sidebar__row-header {
1711+
display: flex;
1712+
flex-direction: row;
1713+
justify-content: space-between;
1714+
}
1715+
.browse-right-sidebar__row-header-text {
17111716
display: inline;
17121717
cursor: default;
17131718
align-self: baseline;
1719+
font-weight: bold;
1720+
font-size: 1.05em;
17141721
}
17151722
.browse-right-sidebar--edit-enabled {
17161723
user-select: none; /* Can not select text while editing is enabled */

typings/flashpoint-launcher.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,6 +2694,7 @@ declare module 'flashpoint-launcher-renderer' {
26942694
onClick?: () => void;
26952695
/** Called whenever the text input changes (must update text value yourself, usually with updateGame) */
26962696
onChange: (value: string) => void;
2697+
HeaderComponent?: (props: GameComponentInputFieldProps) => React.ReactNode;
26972698
};
26982699

26992700
type GameComponentDropdownSelectFieldProps = GameComponentProps & {

0 commit comments

Comments
 (0)