react root node
This commit is contained in:
parent
0d36daacca
commit
4909998144
@ -1,16 +0,0 @@
|
||||
import * as electron from 'electron';
|
||||
import Q from '../q-module';
|
||||
|
||||
export default function bindWindowButtonEvents(q: Q): void {
|
||||
q.$('#minimize').addEventListener('click', () => {
|
||||
electron.ipcRenderer.send('minimize');
|
||||
});
|
||||
|
||||
q.$('#maximize').addEventListener('click', () => {
|
||||
electron.ipcRenderer.send('maximize');
|
||||
});
|
||||
|
||||
q.$('#close').addEventListener('click', () => {
|
||||
electron.ipcRenderer.send('close');
|
||||
});
|
||||
}
|
21
src/client/webapp/elements/root.tsx
Normal file
21
src/client/webapp/elements/root.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import React, { FC } from 'react';
|
||||
import GuildsManager from '../guilds-manager';
|
||||
import GuildsManagerElement from './sections/guilds-manager';
|
||||
import TitleBar from './sections/title-bar';
|
||||
|
||||
export interface RootElementProps {
|
||||
guildsManager: GuildsManager;
|
||||
}
|
||||
|
||||
const RootElement: FC<RootElementProps> = (props: RootElementProps) => {
|
||||
const { guildsManager } = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TitleBar />
|
||||
<GuildsManagerElement guildsManager={guildsManager} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default RootElement;
|
47
src/client/webapp/elements/sections/title-bar.tsx
Normal file
47
src/client/webapp/elements/sections/title-bar.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import React, { FC, useCallback } from 'react';
|
||||
import * as electron from 'electron';
|
||||
|
||||
const TitleBar: FC = () => {
|
||||
const minimize = useCallback(() => {
|
||||
electron.ipcRenderer.send('minimize');
|
||||
}, []);
|
||||
const maximize = useCallback(() => {
|
||||
electron.ipcRenderer.send('maximize');
|
||||
}, []);
|
||||
const close = useCallback(() => {
|
||||
electron.ipcRenderer.send('close');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="title-bar">
|
||||
<div className="app-title">
|
||||
<svg width="55" height="16" viewBox="0 0 55 16">
|
||||
{/* corDis Scraped From Discord Logo and shifted around a bit*/}
|
||||
<path fill="currentColor" d="M2.4237804999999994 6.67391304 L2.4237804999999994 3.32608696 C2.4237804999999994 2.11956522,4.556707299999999 1.83695652,5.203048800000001 3.05434783 L7.174390200000001 2.23913043 C6.4095528 0.510869565,4.987601600000001 0,3.8134146000000015 0 C1.8959349000000003 0,0 1.13043478,0 3.32608696 L0 6.67391304 C0 8.88043478,1.8959349000000003 10,3.7703251999999985 10 C4.976829200000001 10,6.420325200000001 9.39130435,7.217479600000001 7.81521739 L5.106097500000001 6.82608696 C4.5890244 8.17391304,2.4237804999999994 7.84782609,2.4237804999999994 6.67391304 Z M29.376219499999998 0.141304348 L25.7997967 0.141304348 L25.7997967 4.22826087 L28.1804878 6.40217391 L28.1804878 2.43478261 L29.451625999999997 2.43478261 C30.2595528 2.43478261,30.6581301 2.83695652,30.6581301 3.4673913 L30.6581301 6.5 C30.6581301 7.13043478,30.2810975 7.55434783,29.451625999999997 7.55434783 L25.789024400000002 7.55434783 L25.789024400000002 9.85869565 L29.365447099999997 9.85869565 C31.2829268 9.86956522,33.0819105 8.90217391,33.0819105 6.66304348 L33.0819105 3.39130435 C33.0926829 1.13043478,31.2936992 0.141304348,29.376219499999998 0.141304348 Z M11.828048800000001 0 C9.8459349 0,7.8745935 1.09782609,7.8745935 3.33695652 L7.8745935 6.66304348 C7.8745935 8.89130435,9.8567073 10,11.849593500000001 10 C13.831707299999998 10,15.8030488 8.89130435,15.8030488 6.66304348 L15.8030488 3.33695652 C15.8030488 1.10869565,13.810162599999998 0,11.828048800000001 0 Z M13.3792683 6.66304348 C13.3792683 7.35869565,12.603658500000002 7.7173913,11.8388211 7.7173913 C11.0632114 7.7173913,10.287601599999999 7.36956522,10.287601599999999 6.66304348 L10.287601599999999 3.33695652 C10.287601599999999 2.61956522,11.0416666 2.23913043,11.795731700000001 2.23913043 C12.582113800000002 2.23913043,13.3792683 2.58695652,13.3792683 3.33695652 L13.3792683 6.66304348 Z M24.453252 3.33695652 C24.3993902 1.05434783,22.869715399999997 0.141304348,20.898373999999997 0.141304348 L17.074187000000002 0.141304348 L17.074187000000002 9.86956522 L19.5195122 9.86956522 L19.5195122 6.77173913 L19.9504065 6.77173913 L22.1695122 9.85869565 L25.185772299999996 9.85869565 L22.5788618 6.52173913 C23.7422764 6.15217391,24.453252 5.14130435,24.453252 3.33695652 Z M20.941463399999996 4.65217391 L19.5195122 4.65217391 L19.5195122 2.43478261 L20.941463399999996 2.43478261 C22.4711382 2.43478261,22.4711382 4.65217391,20.941463399999996 4.65217391 Z M34.38536586 9.85869565 L36.798373999999995 9.85869565 L36.798373999999995 0.141304348 L34.38536586 0.141304348 L34.38536586 9.85869565 Z M41.5920732 3.7826087 C40.8487805 3.61956522,40.353252 3.34782609,40.320935 2.88043478 C40.3640244 1.75,42.0768293 1.7173913,43.0786585 2.79347826 L44.6621951 1.55434783 C43.6711382 0.326086957,42.550813 0,41.387398399999995 0 C39.6315041 0,37.9294716 1,37.9294716 2.91304348 C37.9294716 4.77173913,39.3298781 5.76086957,40.870325199999996 6 C41.6567073 6.10869565,42.5292683 6.42391304,42.5077236 6.97826087 C42.4430894 8.02173913,40.3317073 7.9673913,39.3729675 6.7826087 L37.8540651 8.23913043 C38.7481707 9.40217391,39.9654472 10,41.1073171 10 C42.8632114 10,44.8130081 8.9673913,44.8884146 7.08695652 C44.9961382 4.69565217,43.2941057 4.09782609,41.5920732 3.7826087 Z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="window-actions">
|
||||
<div className="minimize" onClick={minimize}>
|
||||
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||
{/* Yoinked Directly from Discord */}
|
||||
<rect fill="currentColor" width="10" height="1" x="1" y="6" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="maximize" onClick={maximize}>
|
||||
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||
{/* Yoinked Directly from Discord */}
|
||||
<rect fill="none" stroke="currentColor" width="9" height="9" x="1.5" y="1.5" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="close" onClick={close}>
|
||||
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||
{/* Yoinked Directly from Discord */}
|
||||
<polygon fill="currentColor" fillRule="evenodd" points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TitleBar;
|
@ -6,35 +6,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="./styles/styles.css">
|
||||
</head>
|
||||
<body class="preload">
|
||||
<div id="title-bar">
|
||||
<div id="title">
|
||||
<svg aria-hidden="false" width="55" height="16" viewBox="0 0 55 16">
|
||||
<!-- corDis Scraped From Discord Logo-->
|
||||
<path fill="currentColor" d="M2.4237804999999994 6.67391304 L2.4237804999999994 3.32608696 C2.4237804999999994 2.11956522,4.556707299999999 1.83695652,5.203048800000001 3.05434783 L7.174390200000001 2.23913043 C6.4095528 0.510869565,4.987601600000001 0,3.8134146000000015 0 C1.8959349000000003 0,0 1.13043478,0 3.32608696 L0 6.67391304 C0 8.88043478,1.8959349000000003 10,3.7703251999999985 10 C4.976829200000001 10,6.420325200000001 9.39130435,7.217479600000001 7.81521739 L5.106097500000001 6.82608696 C4.5890244 8.17391304,2.4237804999999994 7.84782609,2.4237804999999994 6.67391304 Z M29.376219499999998 0.141304348 L25.7997967 0.141304348 L25.7997967 4.22826087 L28.1804878 6.40217391 L28.1804878 2.43478261 L29.451625999999997 2.43478261 C30.2595528 2.43478261,30.6581301 2.83695652,30.6581301 3.4673913 L30.6581301 6.5 C30.6581301 7.13043478,30.2810975 7.55434783,29.451625999999997 7.55434783 L25.789024400000002 7.55434783 L25.789024400000002 9.85869565 L29.365447099999997 9.85869565 C31.2829268 9.86956522,33.0819105 8.90217391,33.0819105 6.66304348 L33.0819105 3.39130435 C33.0926829 1.13043478,31.2936992 0.141304348,29.376219499999998 0.141304348 Z M11.828048800000001 0 C9.8459349 0,7.8745935 1.09782609,7.8745935 3.33695652 L7.8745935 6.66304348 C7.8745935 8.89130435,9.8567073 10,11.849593500000001 10 C13.831707299999998 10,15.8030488 8.89130435,15.8030488 6.66304348 L15.8030488 3.33695652 C15.8030488 1.10869565,13.810162599999998 0,11.828048800000001 0 Z M13.3792683 6.66304348 C13.3792683 7.35869565,12.603658500000002 7.7173913,11.8388211 7.7173913 C11.0632114 7.7173913,10.287601599999999 7.36956522,10.287601599999999 6.66304348 L10.287601599999999 3.33695652 C10.287601599999999 2.61956522,11.0416666 2.23913043,11.795731700000001 2.23913043 C12.582113800000002 2.23913043,13.3792683 2.58695652,13.3792683 3.33695652 L13.3792683 6.66304348 Z M24.453252 3.33695652 C24.3993902 1.05434783,22.869715399999997 0.141304348,20.898373999999997 0.141304348 L17.074187000000002 0.141304348 L17.074187000000002 9.86956522 L19.5195122 9.86956522 L19.5195122 6.77173913 L19.9504065 6.77173913 L22.1695122 9.85869565 L25.185772299999996 9.85869565 L22.5788618 6.52173913 C23.7422764 6.15217391,24.453252 5.14130435,24.453252 3.33695652 Z M20.941463399999996 4.65217391 L19.5195122 4.65217391 L19.5195122 2.43478261 L20.941463399999996 2.43478261 C22.4711382 2.43478261,22.4711382 4.65217391,20.941463399999996 4.65217391 Z M34.38536586 9.85869565 L36.798373999999995 9.85869565 L36.798373999999995 0.141304348 L34.38536586 0.141304348 L34.38536586 9.85869565 Z M41.5920732 3.7826087 C40.8487805 3.61956522,40.353252 3.34782609,40.320935 2.88043478 C40.3640244 1.75,42.0768293 1.7173913,43.0786585 2.79347826 L44.6621951 1.55434783 C43.6711382 0.326086957,42.550813 0,41.387398399999995 0 C39.6315041 0,37.9294716 1,37.9294716 2.91304348 C37.9294716 4.77173913,39.3298781 5.76086957,40.870325199999996 6 C41.6567073 6.10869565,42.5292683 6.42391304,42.5077236 6.97826087 C42.4430894 8.02173913,40.3317073 7.9673913,39.3729675 6.7826087 L37.8540651 8.23913043 C38.7481707 9.40217391,39.9654472 10,41.1073171 10 C42.8632114 10,44.8130081 8.9673913,44.8884146 7.08695652 C44.9961382 4.69565217,43.2941057 4.09782609,41.5920732 3.7826087 Z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="window-actions">
|
||||
<div id="minimize">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||
<!-- Yoinked Directly from Discord -->
|
||||
<rect fill="currentColor" width="10" height="1" x="1" y="6" />
|
||||
</svg>
|
||||
</div>
|
||||
<div id="maximize">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||
<!-- Yoinked Directly from Discord -->
|
||||
<rect fill="none" stroke="currentColor" width="9" height="9" x="1.5" y="1.5" />
|
||||
</svg>
|
||||
</div>
|
||||
<div id="close">
|
||||
<svg width="12" height="12" viewBox="0 0 12 12">
|
||||
<!-- Yoinked Directly from Discord -->
|
||||
<polygon fill="currentColor" fill-rule="evenodd" points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="guilds-manager-anchor"></div>
|
||||
<div id="react-root"></div>
|
||||
<!-- it's important that this comes at the end so that these take prescedence over the other absolutely positioned objects-->
|
||||
<div id="react-overlays"></div>
|
||||
</body>
|
||||
|
@ -12,14 +12,12 @@ import GuildsManager from './guilds-manager';
|
||||
|
||||
import Globals from './globals';
|
||||
|
||||
import Q from './q-module';
|
||||
import bindWindowButtonEvents from './elements/events-window-buttons';
|
||||
import PersonalDB from './personal-db';
|
||||
import MessageRAMCache from './message-ram-cache';
|
||||
import ResourceRAMCache from './resource-ram-cache';
|
||||
import ReactDOM from 'react-dom';
|
||||
import React from 'react';
|
||||
import GuildsManagerElement from './elements/sections/guilds-manager';
|
||||
import RootElement from './elements/root';
|
||||
|
||||
LOG.silly('modules loaded');
|
||||
|
||||
@ -58,17 +56,9 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
const guildsManager = new GuildsManager(messageRAMCache, resourceRAMCache, personalDB);
|
||||
await guildsManager.init();
|
||||
|
||||
LOG.silly('guilds manager initialized');
|
||||
|
||||
const q = new Q(document);
|
||||
|
||||
LOG.silly('action classes initialized');
|
||||
|
||||
bindWindowButtonEvents(q);
|
||||
|
||||
LOG.silly('events bound');
|
||||
|
||||
ReactDOM.render(<GuildsManagerElement guildsManager={guildsManager} />, q.$('.guilds-manager-anchor'));
|
||||
ReactDOM.render(<RootElement guildsManager={guildsManager} />, document.getElementById('react-root'));
|
||||
})();
|
||||
});
|
||||
|
||||
|
@ -1,39 +1,39 @@
|
||||
@import "theme.scss";
|
||||
|
||||
#title-bar {
|
||||
.title-bar {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.app-title {
|
||||
color: $text-muted;
|
||||
padding: 6px 0px 0px 10px;
|
||||
flex: 1;
|
||||
-webkit-app-region: drag; /* Also allows for double-click maximise & right-click menu */
|
||||
}
|
||||
|
||||
#title-bar #title {
|
||||
color: $text-muted;
|
||||
padding: 6px 0px 0px 10px;
|
||||
flex: 1;
|
||||
-webkit-app-region: drag; /* Also allows for double-click maximise & right-click menu */
|
||||
}
|
||||
.window-actions {
|
||||
display: flex;
|
||||
|
||||
#title-bar #window-actions {
|
||||
display: flex;
|
||||
}
|
||||
> * {
|
||||
color: $interactive-normal;
|
||||
background: none;
|
||||
border: none;
|
||||
width: 28px;
|
||||
height: 22px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#window-actions > * {
|
||||
color: $interactive-normal;
|
||||
background: none;
|
||||
border: none;
|
||||
width: 28px;
|
||||
height: 22px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.minimize:hover,
|
||||
.maximize:hover {
|
||||
color: $interactive-hover;
|
||||
background-color: $background-modifier-hover;
|
||||
}
|
||||
|
||||
#window-actions #minimize:hover,
|
||||
#window-actions #maximize:hover {
|
||||
color: $interactive-hover;
|
||||
background-color: $background-modifier-hover;
|
||||
}
|
||||
|
||||
#window-actions #close:hover {
|
||||
color: #fff;
|
||||
background-color: #f04747;
|
||||
.close:hover {
|
||||
color: #fff;
|
||||
background-color: #f04747;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,6 @@ import * as path from 'path';
|
||||
|
||||
import * as socketio from 'socket.io-client';
|
||||
|
||||
import Q from './q-module';
|
||||
|
||||
|
||||
interface WithPotentialErrorParams {
|
||||
taskFunc: (() => Promise<void>),
|
||||
errorIndicatorAddFunc: ((element: Element) => Promise<void>),
|
||||
@ -73,16 +70,6 @@ export default class Util {
|
||||
return availableBaseName + ext;
|
||||
}
|
||||
|
||||
// This MUST be called before an errorContainer is removed from the document to prevent memory leaks (if it's parent element is removed, that's the big problem)
|
||||
// This can also be called to remove error indicators from an error container.
|
||||
static removeErrorIndicators(q: Q, errorContainer: HTMLElement, extraClasses?: string[]): void {
|
||||
extraClasses = extraClasses ?? [];
|
||||
const querySelector = '.error-indicator' + extraClasses.map(e => '.' + e).join('');
|
||||
for (const element of q.$$$$(errorContainer, querySelector)) {
|
||||
element.parentElement?.removeChild(element); // The MutationObserver will reject the outstanding Promise
|
||||
}
|
||||
}
|
||||
|
||||
static async sleep(ms: number): Promise<unknown> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
setTimeout(resolve, ms);
|
||||
|
Loading…
Reference in New Issue
Block a user