mirror of
https://github.com/revoltchat/revite.git
synced 2025-02-22 08:11:03 -05:00
feat: full discovery integration
This commit is contained in:
parent
600ea42c0f
commit
540c851d8f
6 changed files with 98 additions and 39 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { Message, Group } from "@styled-icons/boxicons-solid";
|
import { Message, Group, Compass } from "@styled-icons/boxicons-solid";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { useHistory, useLocation } from "react-router";
|
import { useHistory, useLocation } from "react-router";
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
|
@ -56,7 +56,8 @@ export default observer(() => {
|
||||||
|
|
||||||
const friendsActive = path.startsWith("/friends");
|
const friendsActive = path.startsWith("/friends");
|
||||||
const settingsActive = path.startsWith("/settings");
|
const settingsActive = path.startsWith("/settings");
|
||||||
const homeActive = !(friendsActive || settingsActive);
|
const discoverActive = path.startsWith("/discover");
|
||||||
|
const homeActive = !(friendsActive || settingsActive || discoverActive);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Base>
|
<Base>
|
||||||
|
@ -102,6 +103,15 @@ export default observer(() => {
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</ConditionalLink>
|
</ConditionalLink>
|
||||||
</Button>*/}
|
</Button>*/}
|
||||||
|
<Button active={discoverActive}>
|
||||||
|
<ConditionalLink
|
||||||
|
active={discoverActive}
|
||||||
|
to="/discover/servers">
|
||||||
|
<IconButton>
|
||||||
|
<Compass size={24} />
|
||||||
|
</IconButton>
|
||||||
|
</ConditionalLink>
|
||||||
|
</Button>
|
||||||
<Button active={settingsActive}>
|
<Button active={settingsActive}>
|
||||||
<ConditionalLink active={settingsActive} to="/settings">
|
<ConditionalLink active={settingsActive} to="/settings">
|
||||||
<IconButton>
|
<IconButton>
|
||||||
|
|
|
@ -50,10 +50,8 @@ export const ThemeBaseSelectorShim = observer(() => {
|
||||||
* TODO: stabilise
|
* TODO: stabilise
|
||||||
*/
|
*/
|
||||||
export const ThemeShopShim = () => {
|
export const ThemeShopShim = () => {
|
||||||
if (!useApplicationState().experiments.isEnabled("theme_shop")) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link to="/settings/theme_shop" replace>
|
<Link to="/discover/themes" replace>
|
||||||
<CategoryButton
|
<CategoryButton
|
||||||
icon={<Store size={24} />}
|
icon={<Store size={24} />}
|
||||||
action="chevron"
|
action="chevron"
|
||||||
|
|
|
@ -80,10 +80,12 @@ const Routes = styled.div.attrs({ "data-component": "routes" })<{
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const path = useLocation().pathname;
|
const path = useLocation().pathname;
|
||||||
const fixedBottomNav =
|
const fixedBottomNav =
|
||||||
path === "/" || path === "/settings" || path.startsWith("/friends");
|
path === "/" ||
|
||||||
|
path === "/settings" ||
|
||||||
|
path.startsWith("/friends") ||
|
||||||
|
path.startsWith("/discover");
|
||||||
const inChannel = path.includes("/channel");
|
const inChannel = path.includes("/channel");
|
||||||
const inServer = path.includes("/server");
|
const inServer = path.includes("/server");
|
||||||
const inDiscover = path.startsWith("/discover");
|
|
||||||
const inSpecial =
|
const inSpecial =
|
||||||
(path.startsWith("/friends") && isTouchscreenDevice) ||
|
(path.startsWith("/friends") && isTouchscreenDevice) ||
|
||||||
path.startsWith("/invite") ||
|
path.startsWith("/invite") ||
|
||||||
|
@ -118,11 +120,7 @@ export default function App() {
|
||||||
}
|
}
|
||||||
bottomNav={{
|
bottomNav={{
|
||||||
component: <BottomNavigation />,
|
component: <BottomNavigation />,
|
||||||
showIf: inDiscover
|
showIf: fixedBottomNav ? ShowIf.Always : ShowIf.Left,
|
||||||
? 0
|
|
||||||
: fixedBottomNav
|
|
||||||
? ShowIf.Always
|
|
||||||
: ShowIf.Left,
|
|
||||||
height: 50,
|
height: 50,
|
||||||
}}
|
}}
|
||||||
docked={isTouchscreenDevice ? Docked.None : Docked.Left}>
|
docked={isTouchscreenDevice ? Docked.None : Docked.Left}>
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import { LeftArrowAlt } from "@styled-icons/boxicons-regular";
|
|
||||||
import { Compass } from "@styled-icons/boxicons-solid";
|
import { Compass } from "@styled-icons/boxicons-solid";
|
||||||
import { useHistory } from "react-router-dom";
|
import { reaction } from "mobx";
|
||||||
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
|
|
||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||||
|
|
||||||
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice";
|
||||||
|
|
||||||
import { useApplicationState } from "../../mobx/State";
|
import { useApplicationState } from "../../mobx/State";
|
||||||
|
|
||||||
|
import { Overrides } from "../../context/Theme";
|
||||||
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
import { useIntermediate } from "../../context/intermediate/Intermediate";
|
||||||
|
|
||||||
import Header from "../../components/ui/Header";
|
import Header from "../../components/ui/Header";
|
||||||
import IconButton from "../../components/ui/IconButton";
|
|
||||||
import Preloader from "../../components/ui/Preloader";
|
import Preloader from "../../components/ui/Preloader";
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
|
@ -28,6 +28,7 @@ const Container = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
padding-bottom: 50px;
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
`
|
`
|
||||||
: css`
|
: css`
|
||||||
|
@ -54,43 +55,94 @@ const Loader = styled.div`
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const TRUSTED_HOSTS = [
|
||||||
|
"local.revolt.chat:3000",
|
||||||
|
"local.revolt.chat:3001",
|
||||||
|
"rvlt.gg",
|
||||||
|
];
|
||||||
|
|
||||||
export default function Discover() {
|
export default function Discover() {
|
||||||
const layout = useApplicationState().layout;
|
const state = useApplicationState();
|
||||||
const { openLink } = useIntermediate();
|
const { openLink } = useIntermediate();
|
||||||
|
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const { pathname, search } = useLocation();
|
||||||
|
|
||||||
|
const srcURL = useMemo(() => {
|
||||||
|
const query = new URLSearchParams(search);
|
||||||
|
query.set("embedded", "true");
|
||||||
|
// const REMOTE = 'https://rvlt.gg';
|
||||||
|
const REMOTE = "http://local.revolt.chat:3001";
|
||||||
|
return `${REMOTE}${pathname}?${query.toString()}`;
|
||||||
|
}, []);
|
||||||
|
|
||||||
const [loaded, setLoaded] = useState(false);
|
const [loaded, setLoaded] = useState(false);
|
||||||
|
const ref = useRef<HTMLIFrameElement>(null!);
|
||||||
|
|
||||||
useEffect(() => layout.setLastSection("discover"), []);
|
function sendTheme(theme?: Overrides) {
|
||||||
|
ref.current?.contentWindow?.postMessage(
|
||||||
|
JSON.stringify({
|
||||||
|
source: "revolt",
|
||||||
|
type: "theme",
|
||||||
|
theme: theme ?? state.settings.theme.computeVariables(),
|
||||||
|
}),
|
||||||
|
"*",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() =>
|
||||||
|
reaction(() => state.settings.theme.computeVariables(), sendTheme),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => state.layout.setLastSection("discover"), []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function onMessage(message: MessageEvent) {
|
function onMessage(message: MessageEvent) {
|
||||||
let data = JSON.parse(message.data);
|
let url = new URL(message.origin);
|
||||||
if (data.source === "discover") {
|
if (!TRUSTED_HOSTS.includes(url.host)) return;
|
||||||
switch (data.type) {
|
|
||||||
case "navigate": {
|
try {
|
||||||
openLink(data.url);
|
let data = JSON.parse(message.data);
|
||||||
break;
|
if (data.source === "discover") {
|
||||||
|
switch (data.type) {
|
||||||
|
case "init": {
|
||||||
|
sendTheme();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "path": {
|
||||||
|
history.replace(data.path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "navigate": {
|
||||||
|
openLink(data.url);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "applyTheme": {
|
||||||
|
state.settings.theme.hydrate({
|
||||||
|
...data.theme.variables,
|
||||||
|
css: data.theme.css,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("message", onMessage);
|
window.addEventListener("message", onMessage);
|
||||||
return () => window.removeEventListener("message", onMessage);
|
return () => window.removeEventListener("message", onMessage);
|
||||||
});
|
}, [ref]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
{isTouchscreenDevice && (
|
{isTouchscreenDevice && (
|
||||||
<Header placement="primary">
|
<Header placement="primary">
|
||||||
<IconButton
|
|
||||||
onClick={() => history.push(layout.getLastPath())}>
|
|
||||||
<LeftArrowAlt
|
|
||||||
size={27}
|
|
||||||
style={{ marginInlineEnd: "8px" }}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
<Compass size={27} />
|
<Compass size={27} />
|
||||||
Discover
|
Discover
|
||||||
</Header>
|
</Header>
|
||||||
|
@ -101,10 +153,11 @@ export default function Discover() {
|
||||||
</Loader>
|
</Loader>
|
||||||
)}
|
)}
|
||||||
<Frame
|
<Frame
|
||||||
|
ref={ref}
|
||||||
loaded={loaded}
|
loaded={loaded}
|
||||||
crossOrigin="anonymous"
|
crossOrigin="anonymous"
|
||||||
onLoad={() => setLoaded(true)}
|
onLoad={() => setLoaded(true)}
|
||||||
src="https://rvlt.gg/discover/servers?embedded=true"
|
src={srcURL}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
|
@ -56,7 +56,6 @@ import { Notifications } from "./panes/Notifications";
|
||||||
import { Profile } from "./panes/Profile";
|
import { Profile } from "./panes/Profile";
|
||||||
import { Sessions } from "./panes/Sessions";
|
import { Sessions } from "./panes/Sessions";
|
||||||
import { Sync } from "./panes/Sync";
|
import { Sync } from "./panes/Sync";
|
||||||
import { ThemeShop } from "./panes/ThemeShop";
|
|
||||||
|
|
||||||
const AccountHeader = styled.div`
|
const AccountHeader = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -243,11 +242,6 @@ export default observer(() => {
|
||||||
<Route path="/settings/bots">
|
<Route path="/settings/bots">
|
||||||
<MyBots />
|
<MyBots />
|
||||||
</Route>
|
</Route>
|
||||||
{experiments.isEnabled("theme_shop") && (
|
|
||||||
<Route path="/settings/theme_shop">
|
|
||||||
<ThemeShop />
|
|
||||||
</Route>
|
|
||||||
)}
|
|
||||||
<Route path="/settings/feedback">
|
<Route path="/settings/feedback">
|
||||||
<Feedback />
|
<Feedback />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
/**
|
||||||
|
* ! DEPRECATED FILE
|
||||||
|
* ! DO NOT IMPORT
|
||||||
|
*
|
||||||
|
* Replaced by Revolt Discover
|
||||||
|
*/
|
||||||
import { Check } from "@styled-icons/boxicons-regular";
|
import { Check } from "@styled-icons/boxicons-regular";
|
||||||
import {
|
import {
|
||||||
Star,
|
Star,
|
||||||
|
|
Loading…
Add table
Reference in a new issue