From f6a270d67e9a364467d7a9c23899282cafff1fb3 Mon Sep 17 00:00:00 2001 From: Sivert <316918682+grytchat@users.noreply.github.com> Date: Wed, 11 Nov 2026 12:43:27 +0100 Subject: [PATCH] feat(add-server): Gryt Cloud card under "or start your own" The phone can't host, so this is its only way to start a server. It opens gryt.chat/cloud in the browser; nothing is sold in the app. Co-Authored-By: Claude Opus 5.5 --- src/servers/AddServerSheet.tsx | 73 ++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/servers/AddServerSheet.tsx b/src/servers/AddServerSheet.tsx index 5a00c3c..2030501 100644 --- a/src/servers/AddServerSheet.tsx +++ b/src/servers/AddServerSheet.tsx @@ -18,6 +18,9 @@ import { LockIcon } from "phosphor-react-native/src/icons/Lock"; import { UsersThreeIcon } from "phosphor-react-native/src/icons/UsersThree"; import { XIcon } from "phosphor-react-native/src/icons/X"; import { ClipboardTextIcon } from "phosphor-react-native/src/icons/ClipboardText"; +import { CloudIcon } from "phosphor-react-native/src/icons/Cloud"; +import { ArrowSquareOutIcon } from "phosphor-react-native/src/icons/ArrowSquareOut"; +import * as WebBrowser from "expo-web-browser"; import { ServerIcon } from "./ServerIcon"; import { normalizeCode } from "./address"; @@ -35,6 +38,8 @@ import { returnToTabs } from "../shell/returnToTabs"; import { lanDiscoveryAvailable } from "../../modules/lan-discovery"; import { useSheetInsets } from "../shell/useFold"; +const CLOUD_URL = "https://gryt.chat/cloud"; + const JOIN_POLICY_LINE: Partial> = { open: "Anyone can join", request: "Joining needs approval" }; function addLabel(already: boolean, joining: boolean, add: string): string { @@ -243,6 +248,17 @@ function AddServerBody({ setInput(official.host)} /> )} + {/* The phone can't host, so this is its only way to start a server. */} + {empty && ( + + + + + Or run one on your own computer with the desktop app. + + + )} + + + {label} + + + ); +} + +/** Hosting isn't sold yet; this opens the page about it, and payment never happens in the app. */ +function CloudCard() { + const theme = useTheme(); + return ( + void WebBrowser.openBrowserAsync(CLOUD_URL)} + accessibilityRole="link" + accessibilityLabel="Gryt Cloud, coming soon. Opens in your browser." + > + + + + + Gryt Cloud + + Soon + + + + Your own server, always online. We run it for you. + + + + + + ); +} + /** * The server we run, as a row you can press. Pressing it fills the field rather than * joining: everything the join needs already hangs off the address.