mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-25 15:12:08 -05:00
Improved native options.
This commit is contained in:
parent
63d2d1b760
commit
31636d569c
6 changed files with 292 additions and 75 deletions
72
src/components/native/Titlebar.tsx
Normal file
72
src/components/native/Titlebar.tsx
Normal file
|
@ -0,0 +1,72 @@
|
|||
import { X, Minus, Square } from "@styled-icons/boxicons-regular";
|
||||
import styled from "styled-components";
|
||||
|
||||
import wideSVG from "../../assets/wide.svg";
|
||||
|
||||
export const TITLEBAR_HEIGHT = "24px";
|
||||
export const USE_TITLEBAR = window.isNative && !window.native.getConfig().frame;
|
||||
|
||||
const TitlebarBase = styled.div`
|
||||
height: ${TITLEBAR_HEIGHT};
|
||||
|
||||
display: flex;
|
||||
user-select: none;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
flex-grow: 1;
|
||||
-webkit-app-region: drag;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-left: 4px;
|
||||
|
||||
img {
|
||||
width: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
div {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
display: grid;
|
||||
place-items: center;
|
||||
transition: 0.2s ease background-color;
|
||||
|
||||
&:hover {
|
||||
background: var(--primary-background);
|
||||
}
|
||||
|
||||
&.error:hover {
|
||||
background: var(--error);
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function Titlebar() {
|
||||
return (
|
||||
<TitlebarBase>
|
||||
<span class="title">
|
||||
<img src={wideSVG} />
|
||||
</span>
|
||||
<div class="actions">
|
||||
<div onClick={window.native.min}>
|
||||
<Minus size={20} />
|
||||
</div>
|
||||
<div onClick={window.native.max}>
|
||||
<Square size={14} />
|
||||
</div>
|
||||
<div onClick={window.native.close} class="error">
|
||||
<X size={20} />
|
||||
</div>
|
||||
</div>
|
||||
</TitlebarBase>
|
||||
);
|
||||
}
|
8
src/globals.d.ts
vendored
8
src/globals.d.ts
vendored
|
@ -7,12 +7,20 @@ type NativeConfig = {
|
|||
|
||||
declare interface Window {
|
||||
isNative?: boolean;
|
||||
nativeVersion: string;
|
||||
native: {
|
||||
min();
|
||||
max();
|
||||
close();
|
||||
reload();
|
||||
relaunch();
|
||||
|
||||
getConfig(): NativeConfig;
|
||||
setFrame(frame: boolean);
|
||||
setBuild(build: Build);
|
||||
|
||||
getAutoStart(): Promise<boolean>;
|
||||
enableAutoStart(): Promise<void>;
|
||||
disableAutoStart(): Promise<void>;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import Notifications from "../context/revoltjs/Notifications";
|
|||
import StateMonitor from "../context/revoltjs/StateMonitor";
|
||||
import SyncManager from "../context/revoltjs/SyncManager";
|
||||
|
||||
import { TITLEBAR_HEIGHT, USE_TITLEBAR } from "../components/native/Titlebar";
|
||||
import BottomNavigation from "../components/navigation/BottomNavigation";
|
||||
import LeftSidebar from "../components/navigation/LeftSidebar";
|
||||
import RightSidebar from "../components/navigation/RightSidebar";
|
||||
|
@ -42,83 +43,89 @@ export default function App() {
|
|||
path.includes("/settings");
|
||||
|
||||
return (
|
||||
<OverlappingPanels
|
||||
width="100vw"
|
||||
height="var(--app-height)"
|
||||
leftPanel={
|
||||
inSpecial
|
||||
? undefined
|
||||
: { width: 292, component: <LeftSidebar /> }
|
||||
}
|
||||
rightPanel={
|
||||
!inSpecial && inChannel
|
||||
? { width: 240, component: <RightSidebar /> }
|
||||
: undefined
|
||||
}
|
||||
bottomNav={{
|
||||
component: <BottomNavigation />,
|
||||
showIf: fixedBottomNav ? ShowIf.Always : ShowIf.Left,
|
||||
height: 50,
|
||||
}}
|
||||
docked={isTouchscreenDevice ? Docked.None : Docked.Left}>
|
||||
<Routes>
|
||||
<Switch>
|
||||
<Route
|
||||
path="/server/:server/channel/:channel/settings/:page"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/channel/:channel/settings"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/settings/:page"
|
||||
component={ServerSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/settings"
|
||||
component={ServerSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/channel/:channel/settings/:page"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/channel/:channel/settings"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
<>
|
||||
<OverlappingPanels
|
||||
width="100vw"
|
||||
height={
|
||||
USE_TITLEBAR
|
||||
? `calc(var(--app-height) - ${TITLEBAR_HEIGHT})`
|
||||
: "var(--app-height)"
|
||||
}
|
||||
leftPanel={
|
||||
inSpecial
|
||||
? undefined
|
||||
: { width: 292, component: <LeftSidebar /> }
|
||||
}
|
||||
rightPanel={
|
||||
!inSpecial && inChannel
|
||||
? { width: 240, component: <RightSidebar /> }
|
||||
: undefined
|
||||
}
|
||||
bottomNav={{
|
||||
component: <BottomNavigation />,
|
||||
showIf: fixedBottomNav ? ShowIf.Always : ShowIf.Left,
|
||||
height: 50,
|
||||
}}
|
||||
docked={isTouchscreenDevice ? Docked.None : Docked.Left}>
|
||||
<Routes>
|
||||
<Switch>
|
||||
<Route
|
||||
path="/server/:server/channel/:channel/settings/:page"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/channel/:channel/settings"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/settings/:page"
|
||||
component={ServerSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/settings"
|
||||
component={ServerSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/channel/:channel/settings/:page"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
<Route
|
||||
path="/channel/:channel/settings"
|
||||
component={ChannelSettings}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/channel/:channel/:message"
|
||||
component={Channel}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/channel/:channel/:message"
|
||||
component={Channel}
|
||||
/>
|
||||
<Route
|
||||
path="/channel/:channel/:message"
|
||||
component={Channel}
|
||||
/>
|
||||
<Route
|
||||
path="/server/:server/channel/:channel/:message"
|
||||
component={Channel}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/server/:server/channel/:channel"
|
||||
component={Channel}
|
||||
/>
|
||||
<Route path="/server/:server" />
|
||||
<Route path="/channel/:channel" component={Channel} />
|
||||
<Route
|
||||
path="/server/:server/channel/:channel"
|
||||
component={Channel}
|
||||
/>
|
||||
<Route path="/server/:server" />
|
||||
<Route path="/channel/:channel" component={Channel} />
|
||||
|
||||
<Route path="/settings/:page" component={Settings} />
|
||||
<Route path="/settings" component={Settings} />
|
||||
<Route path="/settings/:page" component={Settings} />
|
||||
<Route path="/settings" component={Settings} />
|
||||
|
||||
<Route path="/dev" component={Developer} />
|
||||
<Route path="/friends" component={Friends} />
|
||||
<Route path="/open/:id" component={Open} />
|
||||
<Route path="/invite/:code" component={Invite} />
|
||||
<Route path="/" component={Home} />
|
||||
</Switch>
|
||||
</Routes>
|
||||
<ContextMenus />
|
||||
<Popovers />
|
||||
<Notifications />
|
||||
<StateMonitor />
|
||||
<SyncManager />
|
||||
</OverlappingPanels>
|
||||
<Route path="/dev" component={Developer} />
|
||||
<Route path="/friends" component={Friends} />
|
||||
<Route path="/open/:id" component={Open} />
|
||||
<Route path="/invite/:code" component={Invite} />
|
||||
<Route path="/" component={Home} />
|
||||
</Switch>
|
||||
</Routes>
|
||||
<ContextMenus />
|
||||
<Popovers />
|
||||
<Notifications />
|
||||
<StateMonitor />
|
||||
<SyncManager />
|
||||
</OverlappingPanels>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ import { CheckAuth } from "../context/revoltjs/CheckAuth";
|
|||
import Masks from "../components/ui/Masks";
|
||||
import Preloader from "../components/ui/Preloader";
|
||||
|
||||
import { Titlebar, USE_TITLEBAR } from "../components/native/Titlebar";
|
||||
|
||||
const Login = lazy(() => import("./login/Login"));
|
||||
const RevoltApp = lazy(() => import("./RevoltApp"));
|
||||
|
||||
|
@ -15,6 +17,7 @@ export function App() {
|
|||
return (
|
||||
<Context>
|
||||
<Masks />
|
||||
{USE_TITLEBAR && <Titlebar />}
|
||||
{/*
|
||||
// @ts-expect-error */}
|
||||
<Suspense fallback={<Preloader type="spinner" />}>
|
||||
|
|
|
@ -210,6 +210,9 @@ export default function Settings() {
|
|||
{GIT_BRANCH === "production" ? "Stable" : "Nightly"}{" "}
|
||||
{APP_VERSION}
|
||||
</span>
|
||||
{window.isNative && (
|
||||
<span>Native: {window.nativeVersion}</span>
|
||||
)}
|
||||
<span>
|
||||
API: {client.configuration?.revolt ?? "N/A"}
|
||||
</span>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { useEffect, useState } from "preact/hooks";
|
||||
|
||||
import { SyncOptions } from "../../../redux/reducers/sync";
|
||||
|
||||
import Button from "../../../components/ui/Button";
|
||||
import Checkbox from "../../../components/ui/Checkbox";
|
||||
|
||||
interface Props {
|
||||
|
@ -7,5 +10,126 @@ interface Props {
|
|||
}
|
||||
|
||||
export function Native(props: Props) {
|
||||
return <div></div>;
|
||||
const [config, setConfig] = useState(window.native.getConfig());
|
||||
const [autoStart, setAutoStart] = useState<boolean | undefined>();
|
||||
const fetchValue = () => window.native.getAutoStart().then(setAutoStart);
|
||||
|
||||
const [hintReload, setHintReload] = useState(false);
|
||||
const [hintRelaunch, setHintRelaunch] = useState(false);
|
||||
const [confirmDev, setConfirmDev] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchValue();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Checkbox
|
||||
checked={autoStart ?? false}
|
||||
disabled={typeof autoStart === "undefined"}
|
||||
onChange={async (v) => {
|
||||
if (v) {
|
||||
await window.native.enableAutoStart();
|
||||
} else {
|
||||
await window.native.disableAutoStart();
|
||||
}
|
||||
|
||||
setAutoStart(v);
|
||||
}}
|
||||
description="Launch Revolt when you log into your computer.">
|
||||
Start with computer
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={!config.frame}
|
||||
onChange={(frame) => {
|
||||
window.native.setFrame(!frame);
|
||||
setHintRelaunch(true);
|
||||
setConfig({
|
||||
...config,
|
||||
frame: !frame,
|
||||
});
|
||||
}}
|
||||
description={<>Let Revolt use its own window frame.</>}>
|
||||
Custom window frame
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
checked={config.build === "nightly"}
|
||||
onChange={(nightly) => {
|
||||
const build = nightly ? "nightly" : "stable";
|
||||
window.native.setBuild(build);
|
||||
setHintReload(true);
|
||||
setConfig({
|
||||
...config,
|
||||
build,
|
||||
});
|
||||
}}
|
||||
description={<>Use the beta branch of Revolt.</>}>
|
||||
Revolt Nightly
|
||||
</Checkbox>
|
||||
<p style={{ display: "flex", gap: "8px" }}>
|
||||
<Button
|
||||
contrast
|
||||
compact
|
||||
disabled={!hintReload}
|
||||
onClick={window.native.reload}>
|
||||
Reload Page
|
||||
</Button>
|
||||
<Button
|
||||
contrast
|
||||
compact
|
||||
disabled={!hintRelaunch}
|
||||
onClick={window.native.relaunch}>
|
||||
Reload App
|
||||
</Button>
|
||||
</p>
|
||||
<h3 style={{ marginTop: "4em" }}>Local Development Mode</h3>
|
||||
{config.build === "dev" ? (
|
||||
<p>
|
||||
<Button
|
||||
contrast
|
||||
compact
|
||||
onClick={() => {
|
||||
window.native.setBuild("stable");
|
||||
window.native.reload();
|
||||
}}>
|
||||
Exit Development Mode
|
||||
</Button>
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
<Checkbox
|
||||
checked={confirmDev}
|
||||
onChange={setConfirmDev}
|
||||
description={
|
||||
<>
|
||||
This will change the app to the 'dev' branch,
|
||||
instead loading the app from a local server on
|
||||
your machine.
|
||||
<br />
|
||||
<b>
|
||||
Without a server running,{" "}
|
||||
<span style={{ color: "var(--error)" }}>
|
||||
the app will not load!
|
||||
</span>
|
||||
</b>
|
||||
</>
|
||||
}>
|
||||
I understand there's no going back.
|
||||
</Checkbox>
|
||||
<p>
|
||||
<Button
|
||||
error
|
||||
compact
|
||||
disabled={!confirmDev}
|
||||
onClick={() => {
|
||||
window.native.setBuild("dev");
|
||||
window.native.reload();
|
||||
}}>
|
||||
Enter Development Mode
|
||||
</Button>
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue