diff --git a/Dockerfile b/Dockerfile index 779109edaf..a9bd7c6ba2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,13 +35,9 @@ RUN pnpm --filter client exec lingui compile --typescript # Build the client with placeholder env vars for runtime injection # these are replaced by inject.js at container run startup +ENV VITE_HOST=__VITE_HOST__ ENV VITE_API_URL=__VITE_API_URL__ -ENV VITE_WS_URL=__VITE_WS_URL__ -ENV VITE_MEDIA_URL=__VITE_MEDIA_URL__ -ENV VITE_PROXY_URL=__VITE_PROXY_URL__ ENV VITE_HCAPTCHA_SITEKEY=__VITE_HCAPTCHA_SITEKEY__ -ENV VITE_CFG_ENABLE_VIDEO=__VITE_CFG_ENABLE_VIDEO__ -ENV VITE_GIFBOX_URL=__VITE_GIFBOX_URL__ ENV VITE_RNNOISE_WORKLET_CDN_URL=__VITE_RNNOISE_WORKLET_CDN_URL__ ARG BASE_PATH=/ @@ -67,12 +63,7 @@ EXPOSE 5000 # Runtime env vars (overridden by Helm chart / docker run) ENV VITE_API_URL="" -ENV VITE_WS_URL="" -ENV VITE_MEDIA_URL="" -ENV VITE_PROXY_URL="" ENV VITE_HCAPTCHA_SITEKEY="" -ENV VITE_CFG_ENABLE_VIDEO="" -ENV VITE_GIFBOX_URL="" ENV VITE_RNNOISE_WORKLET_CDN_URL="" CMD ["npm", "start"] diff --git a/README.md b/README.md index 4b2e62b273..f72b1963ce 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,6 @@ If you want the client to connect to the official hosted backend instead, open t ```env # connect to local Stoat instance #VITE_API_URL=http://localhost:14702 -#VITE_WS_URL=ws://localhost:14703 -#VITE_MEDIA_URL=http://localhost:14704 -#VITE_PROXY_URL=http://localhost:14705 - ``` When these variables are not set, the client automatically falls back to the official backend. (See https://github.com/stoatchat/for-web/blob/main/packages/client/components/common/lib/env.ts) diff --git a/docker/inject.js b/docker/inject.js index 12eb49fdac..399b7c4efb 100644 --- a/docker/inject.js +++ b/docker/inject.js @@ -14,14 +14,11 @@ const OUT_DIR = "dist_injected"; // At build time, Vite replaces import.meta.env.VITE_X with the literal string value. // We build with placeholder values like "__VITE_API_URL__" so they appear in the output. const REPLACEMENTS = { + __VITE_HOST__: process.env.VITE_HOST || "", __VITE_API_URL__: process.env.VITE_API_URL || "", - __VITE_WS_URL__: process.env.VITE_WS_URL || "", - __VITE_MEDIA_URL__: process.env.VITE_MEDIA_URL || "", - __VITE_PROXY_URL__: process.env.VITE_PROXY_URL || "", __VITE_HCAPTCHA_SITEKEY__: process.env.VITE_HCAPTCHA_SITEKEY || "", - __VITE_CFG_ENABLE_VIDEO__: process.env.VITE_CFG_ENABLE_VIDEO || "", - __VITE_GIFBOX_URL__: process.env.VITE_GIFBOX_URL || "", - __VITE_RNNOISE_WORKLET_CDN_URL__: process.env.VITE_RNNOISE_WORKLET_CDN_URL || "", + __VITE_RNNOISE_WORKLET_CDN_URL__: + process.env.VITE_RNNOISE_WORKLET_CDN_URL || "", }; console.log("Preparing injected build..."); diff --git a/packages/client/.env.example b/packages/client/.env.example index 20ee85f12a..3183e2f485 100644 --- a/packages/client/.env.example +++ b/packages/client/.env.example @@ -1,16 +1,10 @@ # connect to local Stoat instance +VITE_HOST=localhost:4173 VITE_API_URL=http://localhost:14702 -VITE_WS_URL=ws://localhost:14703 -VITE_MEDIA_URL=http://localhost:14704 -VITE_PROXY_URL=http://localhost:14705 -VITE_GIFBOX_URL=http://localhost:14706 # specify hCaptcha sitekey VITE_HCAPTCHA_SITEKEY= # specify Sentry DSN VITE_SENTRY_DSN= -VITE_SENTRY_TUNNEL= - -# configs -VITE_CFG_ENABLE_VIDEO= \ No newline at end of file +VITE_SENTRY_TUNNEL= \ No newline at end of file diff --git a/packages/client/components/app/interface/settings/Settings.tsx b/packages/client/components/app/interface/settings/Settings.tsx index d7504d46c1..508b34bf3f 100644 --- a/packages/client/components/app/interface/settings/Settings.tsx +++ b/packages/client/components/app/interface/settings/Settings.tsx @@ -147,7 +147,10 @@ export function Settings(props: SettingsProps & SettingsConfiguration) { easing: [0.17, 0.67, 0.58, 0.98], }} > - {props.render({ page }, props.context)} + {props.render( + { page, onClose: props.onClose }, + props.context, + )} diff --git a/packages/client/components/app/interface/settings/UserSettings.tsx b/packages/client/components/app/interface/settings/UserSettings.tsx index 01a503f598..3fccb172e7 100644 --- a/packages/client/components/app/interface/settings/UserSettings.tsx +++ b/packages/client/components/app/interface/settings/UserSettings.tsx @@ -5,7 +5,7 @@ import { Server } from "stoat.js"; import { css } from "styled-system/css"; import { useClient, useClientLifecycle } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { useUser } from "@revolt/markdown/users"; import { useModals } from "@revolt/modal"; import { fetchLatestChangelog } from "@revolt/modal/modals/Changelog"; @@ -77,7 +77,7 @@ const Config: SettingsConfiguration<{ server: Server }> = { switch (id) { case "account": - return ; + return ; case "appearance": return ; case "advanced": @@ -114,6 +114,7 @@ const Config: SettingsConfiguration<{ server: Server }> = { list(_, onClose) { const { pop, openModal } = useModals(); const { logout } = useClientLifecycle(); + const { limits } = useInstance(); return { context: null!, @@ -213,7 +214,7 @@ const Config: SettingsConfiguration<{ server: Server }> = { { id: "voice", icon: , - title: CONFIGURATION.ENABLE_VIDEO ? ( + title: limits().video ? ( Voice & Video ) : ( Voice diff --git a/packages/client/components/app/interface/settings/channel/Overview.tsx b/packages/client/components/app/interface/settings/channel/Overview.tsx index d9edea8486..a7edc96f7f 100644 --- a/packages/client/components/app/interface/settings/channel/Overview.tsx +++ b/packages/client/components/app/interface/settings/channel/Overview.tsx @@ -5,7 +5,7 @@ import { Trans, useLingui } from "@lingui-solid/solid/macro"; import type { API } from "stoat.js"; import { useClient } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { useModals } from "@revolt/modal"; import { Button, @@ -26,6 +26,7 @@ export default function ChannelOverview(props: ChannelSettingsProps) { const { t } = useLingui(); const client = useClient(); const { openModal } = useModals(); + const instance = useInstance(); /* eslint-disable solid/reactivity */ // we want to take the initial value only @@ -77,16 +78,13 @@ export default function ChannelOverview(props: ChannelSettingsProps) { body.append("file", editGroup.controls.icon.value[0]); const [key, value] = client().authenticationHeader; - const data: { id: string } = await fetch( - `${CONFIGURATION.DEFAULT_MEDIA_URL}/icons`, - { - method: "POST", - body, - headers: { - [key]: value, - }, + const data: { id: string } = await fetch(`${instance.mediaUrl}/icons`, { + method: "POST", + body, + headers: { + [key]: value, }, - ).then((res) => res.json()); + }).then((res) => res.json()); changes.icon = data.id; } diff --git a/packages/client/components/app/interface/settings/channel/webhooks/ViewWebhook.tsx b/packages/client/components/app/interface/settings/channel/webhooks/ViewWebhook.tsx index 1210aeacf3..84dbf564b2 100644 --- a/packages/client/components/app/interface/settings/channel/webhooks/ViewWebhook.tsx +++ b/packages/client/components/app/interface/settings/channel/webhooks/ViewWebhook.tsx @@ -6,7 +6,7 @@ import { useMutation } from "@tanstack/solid-query"; import { API, ChannelWebhook } from "stoat.js"; import { useClient } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { useModals } from "@revolt/modal"; import { CategoryButton, @@ -29,6 +29,7 @@ export function ViewWebhook(props: { webhook: ChannelWebhook }) { const client = useClient(); const { showError } = useModals(); const { navigate } = useSettingsNavigation(); + const instance = useInstance(); /* eslint-disable solid/reactivity */ const editGroup = createFormGroup({ @@ -63,7 +64,7 @@ export function ViewWebhook(props: { webhook: ChannelWebhook }) { const [key, value] = client().authenticationHeader; const data: { id: string } = await fetch( - `${CONFIGURATION.DEFAULT_MEDIA_URL}/avatars`, + `${instance.mediaUrl}/avatars`, { method: "POST", body, @@ -120,7 +121,9 @@ export function ViewWebhook(props: { webhook: ChannelWebhook }) { icon={} onClick={() => navigator.clipboard.writeText( - `${CONFIGURATION.DEFAULT_API_URL}/webhooks/${props.webhook.id}/${props.webhook.token}`, + instance.href( + `/webhooks/${props.webhook.id}/${props.webhook.token}`, + ), ) } > diff --git a/packages/client/components/app/interface/settings/index.tsx b/packages/client/components/app/interface/settings/index.tsx index d41573f794..d1eddb26c4 100644 --- a/packages/client/components/app/interface/settings/index.tsx +++ b/packages/client/components/app/interface/settings/index.tsx @@ -26,7 +26,10 @@ export type SettingsConfiguration = { * @param props State information */ render: ( - props: { page: Accessor }, + props: { + page: Accessor; + onClose?: () => void; + }, context: T, ) => JSX.Element; }; diff --git a/packages/client/components/app/interface/settings/server/Overview.tsx b/packages/client/components/app/interface/settings/server/Overview.tsx index b2be570e55..573bc1af1f 100644 --- a/packages/client/components/app/interface/settings/server/Overview.tsx +++ b/packages/client/components/app/interface/settings/server/Overview.tsx @@ -5,7 +5,7 @@ import { Trans, useLingui } from "@lingui-solid/solid/macro"; import type { API } from "stoat.js"; import { useClient } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { CircularProgress, Column, @@ -23,6 +23,7 @@ import { ServerSettingsProps } from "../ServerSettings"; export default function ServerOverview(props: ServerSettingsProps) { const { t } = useLingui(); const client = useClient(); + const instance = useInstance(); /* eslint-disable solid/reactivity */ const editGroup = createFormGroup({ @@ -144,7 +145,7 @@ export default function ServerOverview(props: ServerSettingsProps) { changes.icon = await client().uploadFile( "icons", editGroup.controls.icon.value[0], - CONFIGURATION.DEFAULT_MEDIA_URL, + instance.mediaUrl, ); } } @@ -156,7 +157,7 @@ export default function ServerOverview(props: ServerSettingsProps) { changes.banner = await client().uploadFile( "banners", editGroup.controls.banner.value[0], - CONFIGURATION.DEFAULT_MEDIA_URL, + instance.mediaUrl, ); } } diff --git a/packages/client/components/app/interface/settings/server/emojis/EmojiList.tsx b/packages/client/components/app/interface/settings/server/emojis/EmojiList.tsx index f10af5e1b4..63241badea 100644 --- a/packages/client/components/app/interface/settings/server/emojis/EmojiList.tsx +++ b/packages/client/components/app/interface/settings/server/emojis/EmojiList.tsx @@ -6,8 +6,8 @@ import { Server } from "stoat.js"; import { css } from "styled-system/css"; import { useClient } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; import { useError } from "@revolt/i18n"; +import { useInstance } from "@revolt/instance"; import { useModals } from "@revolt/modal"; import { Avatar, @@ -27,9 +27,10 @@ export function EmojiList(props: { server: Server }) { const { t } = useLingui(); const client = useClient(); const { openModal } = useModals(); + const instance = useInstance(); function isDisabled() { - return props.server.emojis.length >= CONFIGURATION.MAX_EMOJI; + return props.server.emojis.length >= instance.globalLimits.server_emoji; } const editGroup = createFormGroup( @@ -49,16 +50,13 @@ export function EmojiList(props: { server: Server }) { body.append("file", editGroup.controls.file.value![0]); const [key, value] = client().authenticationHeader; - const data: { id: string } = await fetch( - `${CONFIGURATION.DEFAULT_MEDIA_URL}/emojis`, - { - method: "POST", - body, - headers: { - [key]: value, - }, + const data: { id: string } = await fetch(`${instance.mediaUrl}/emojis`, { + method: "POST", + body, + headers: { + [key]: value, }, - ).then((res) => res.json()); + }).then((res) => res.json()); await props.server.createEmoji(data.id, { name: editGroup.controls.name.value, @@ -102,7 +100,8 @@ export function EmojiList(props: { server: Server }) { - {CONFIGURATION.MAX_EMOJI - props.server.emojis.length}{" "} + {instance.globalLimits.server_emoji - + props.server.emojis.length}{" "} emoji slots remaining } diff --git a/packages/client/components/app/interface/settings/server/roles/ServerRoleEditor.tsx b/packages/client/components/app/interface/settings/server/roles/ServerRoleEditor.tsx index 7e5fa909d7..591063da80 100644 --- a/packages/client/components/app/interface/settings/server/roles/ServerRoleEditor.tsx +++ b/packages/client/components/app/interface/settings/server/roles/ServerRoleEditor.tsx @@ -1,9 +1,12 @@ +import { For, Show, createMemo, createSignal } from "solid-js"; + import { Trans, useLingui } from "@lingui-solid/solid/macro"; -import MdContentCopy from "@material-design-icons/svg/outlined/content_copy.svg?component-solid"; -import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; -import MDPalette from "@material-design-icons/svg/outlined/palette.svg?component-solid"; +import { createFormControl, createFormGroup } from "solid-forms"; +import { API, Server, ServerRole } from "stoat.js"; +import { styled } from "styled-system/jsx"; + import { useClient } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { useModals } from "@revolt/modal"; import { Button, @@ -15,10 +18,11 @@ import { Row, Text, } from "@revolt/ui"; -import { createFormControl, createFormGroup } from "solid-forms"; -import { For, Show, createMemo, createSignal } from "solid-js"; -import { API, Server, ServerRole } from "stoat.js"; -import { styled } from "styled-system/jsx"; + +import MdContentCopy from "@material-design-icons/svg/outlined/content_copy.svg?component-solid"; +import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; +import MDPalette from "@material-design-icons/svg/outlined/palette.svg?component-solid"; + import { useSettingsNavigation } from "../../Settings"; import { ChannelPermissionsEditor } from "../../channel/permissions/ChannelPermissionsEditor"; @@ -30,6 +34,7 @@ export function ServerRoleEditor(props: { context: Server; roleId: string }) { const client = useClient(); const { openModal } = useModals(); const { navigate } = useSettingsNavigation(); + const instance = useInstance(); const role = createMemo( () => @@ -65,7 +70,7 @@ export function ServerRoleEditor(props: { context: Server; roleId: string }) { changes.icon = await client().uploadFile( "icons", editGroup.controls.icon.value[0], - CONFIGURATION.DEFAULT_MEDIA_URL, + instance.mediaUrl, ); } } diff --git a/packages/client/components/app/interface/settings/user/Account.tsx b/packages/client/components/app/interface/settings/user/Account.tsx index c4e7e44464..146ee2a2be 100644 --- a/packages/client/components/app/interface/settings/user/Account.tsx +++ b/packages/client/components/app/interface/settings/user/Account.tsx @@ -13,19 +13,19 @@ import { CategoryButton, Column, Row, iconSize } from "@revolt/ui"; import MdAlternateEmail from "@material-design-icons/svg/outlined/alternate_email.svg?component-solid"; import MdBlock from "@material-design-icons/svg/outlined/block.svg?component-solid"; import MdDelete from "@material-design-icons/svg/outlined/delete.svg?component-solid"; +import MdAddUser from "@material-design-icons/svg/outlined/group_add.svg?component-solid"; import MdLock from "@material-design-icons/svg/outlined/lock.svg?component-solid"; import MdMail from "@material-design-icons/svg/outlined/mail.svg?component-solid"; import MdPassword from "@material-design-icons/svg/outlined/password.svg?component-solid"; import MdVerifiedUser from "@material-design-icons/svg/outlined/verified_user.svg?component-solid"; import { useSettingsNavigation } from "../Settings"; - import { UserSummary } from "./account/index"; /** * Account Page */ -export function MyAccount() { +export function MyAccount(props: { onClose?: () => void }) { const client = useClient(); const profile = createOwnProfileResource(); const { navigate } = useSettingsNavigation(); @@ -38,7 +38,7 @@ export function MyAccount() { onEdit={() => navigate("profile")} showBadges /> - + @@ -48,13 +48,27 @@ export function MyAccount() { /** * Edit account details */ -function EditAccount() { +function EditAccount(props: { onClose?: () => void }) { const client = useClient(); const { openModal } = useModals(); + const { stow } = useClientLifecycle(); const [email, setEmail] = createSignal("•••••••••••@•••••••••••"); return ( + { + props.onClose?.(); + stow(); + }} + icon={} + description={ + Add an additional account login for fast-switching + } + > + Add an account + diff --git a/packages/client/components/app/interface/settings/user/Feedback.tsx b/packages/client/components/app/interface/settings/user/Feedback.tsx index 813ccb54d1..5841c3eddb 100644 --- a/packages/client/components/app/interface/settings/user/Feedback.tsx +++ b/packages/client/components/app/interface/settings/user/Feedback.tsx @@ -11,7 +11,7 @@ import MdFormatListNumbered from "@material-design-icons/svg/outlined/format_lis import MdStar from "@material-design-icons/svg/outlined/star_outline.svg?component-solid"; import { useClient } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { useModals } from "@revolt/modal"; import { CategoryButton, Column, iconSize } from "@revolt/ui"; @@ -22,8 +22,9 @@ export function Feedback() { const { openModal, pop } = useModals(); const navigate = useNavigate(); const client = useClient(); + const instance = useInstance(); - const showLoungeButton = CONFIGURATION.IS_STOAT; + const showLoungeButton = instance.isStoat; const isInLounge = client()!.servers.get("01F7ZSBSFHQ8TA81725KQCSDDP") !== undefined; diff --git a/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx b/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx index dbecb24719..ec877d2696 100644 --- a/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx +++ b/packages/client/components/app/interface/settings/user/bots/ViewBot.tsx @@ -2,6 +2,7 @@ import { Trans, useLingui } from "@lingui-solid/solid/macro"; import { Bot } from "stoat.js"; import { createProfileResource } from "@revolt/client/resources"; +import { useInstance } from "@revolt/instance"; import { useModals } from "@revolt/modal"; import { CategoryButton, Column, iconSize, useSnackbar } from "@revolt/ui"; @@ -23,6 +24,7 @@ export function ViewBot(props: { bot: Bot }) { // `bot` will never change, so we don't care about reactivity here // eslint-disable-next-line solid/reactivity const profile = createProfileResource(props.bot.user!); + const instance = useInstance(); const { openModal } = useModals(); const snackbar = useSnackbar(); const { t } = useLingui(); @@ -82,9 +84,8 @@ export function ViewBot(props: { bot: Bot }) { action="copy" onClick={() => { navigator.clipboard.writeText( - new URL(`/bot/${props.bot.id}`, window.origin).toString(), + instance.href(`/bot/${props.bot.id}`), ); - snackbar.show({ message: t`Invite URL copied to clipboard`, placement: "bottom", diff --git a/packages/client/components/app/interface/settings/user/profile/UserProfileEditor.tsx b/packages/client/components/app/interface/settings/user/profile/UserProfileEditor.tsx index 3c0ef21dd2..c015d12777 100644 --- a/packages/client/components/app/interface/settings/user/profile/UserProfileEditor.tsx +++ b/packages/client/components/app/interface/settings/user/profile/UserProfileEditor.tsx @@ -6,7 +6,7 @@ import { useQuery, useQueryClient } from "@tanstack/solid-query"; import { API, User } from "stoat.js"; import { useClient } from "@revolt/client"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { CategoryButton, CircularProgress, @@ -28,6 +28,7 @@ export function UserProfileEditor(props: Props) { const { t } = useLingui(); const client = useClient(); const queryClient = useQueryClient(); + const instance = useInstance(); const profile = useQuery(() => ({ queryKey: ["profile", props.user.id], @@ -102,7 +103,7 @@ export function UserProfileEditor(props: Props) { changes.avatar = await client().uploadFile( "avatars", editGroup.controls.avatar.value[0], - CONFIGURATION.DEFAULT_MEDIA_URL, + instance.mediaUrl, ); } } @@ -126,10 +127,10 @@ export function UserProfileEditor(props: Props) { changes.profile.background = await client().uploadFile( "backgrounds", editGroup.controls.banner.value[0], - CONFIGURATION.DEFAULT_MEDIA_URL, + instance.mediaUrl, ); - newBannerUrl = `${CONFIGURATION.DEFAULT_MEDIA_URL}/backgrounds/${changes.profile.background}`; + newBannerUrl = `${instance.mediaUrl}/backgrounds/${changes.profile.background}`; } else { newBannerUrl = editGroup.controls.banner.value; } diff --git a/packages/client/components/app/interface/settings/user/voice/VoiceInputOptions.tsx b/packages/client/components/app/interface/settings/user/voice/VoiceInputOptions.tsx index c60be14665..10ffbe9b56 100644 --- a/packages/client/components/app/interface/settings/user/voice/VoiceInputOptions.tsx +++ b/packages/client/components/app/interface/settings/user/voice/VoiceInputOptions.tsx @@ -3,7 +3,7 @@ import { useMediaDeviceSelect } from "solid-livekit-components"; import { Trans } from "@lingui-solid/solid/macro"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { useState } from "@revolt/state"; import { CategoryButton, @@ -18,12 +18,14 @@ import { Symbol } from "@revolt/ui/components/utils/Symbol"; * Input options */ export function VoiceInputOptions() { + const { limits } = useInstance(); + return ( - + diff --git a/packages/client/components/app/interface/settings/user/voice/VoiceSettings.tsx b/packages/client/components/app/interface/settings/user/voice/VoiceSettings.tsx index c40d73de7e..a11ef5ce5d 100644 --- a/packages/client/components/app/interface/settings/user/voice/VoiceSettings.tsx +++ b/packages/client/components/app/interface/settings/user/voice/VoiceSettings.tsx @@ -1,20 +1,23 @@ import { Show } from "solid-js"; -import { CONFIGURATION } from "@revolt/common"; +import { useInstance } from "@revolt/instance"; import { Column } from "@revolt/ui"; import { ScreenShareOptions } from "./ScreenShareOptions"; import { VoiceInputOptions } from "./VoiceInputOptions"; import { VoiceProcessingOptions } from "./VoiceProcessingOptions"; + /** * Configure voice options */ export function VoiceSettings() { + const { limits } = useInstance(); + return ( - + diff --git a/packages/client/components/app/menus/ChannelContextMenu.tsx b/packages/client/components/app/menus/ChannelContextMenu.tsx index 206465ac52..11d8992577 100644 --- a/packages/client/components/app/menus/ChannelContextMenu.tsx +++ b/packages/client/components/app/menus/ChannelContextMenu.tsx @@ -3,6 +3,7 @@ import { Match, Show, Switch } from "solid-js"; import { Trans } from "@lingui-solid/solid/macro"; import { Channel } from "stoat.js"; +import { useInstance } from "@revolt/instance"; import { useModals } from "@revolt/modal"; import { useState } from "@revolt/state"; @@ -28,6 +29,7 @@ import { NotificationContextMenu } from "./shared/NotificationContextMenu"; */ export function ChannelContextMenu(props: { channel: Channel }) { const state = useState(); + const instance = useInstance(); const { openModal } = useModals(); /** @@ -93,9 +95,11 @@ export function ChannelContextMenu(props: { channel: Channel }) { */ function copyLink() { navigator.clipboard.writeText( - `${location.origin}${ - props.channel.server ? `/server/${props.channel.server?.id}` : "" - }/channel/${props.channel.id}`, + instance.href( + `${ + props.channel.server ? `/server/${props.channel.server?.id}` : "" + }/channel/${props.channel.id}`, + ), ); } diff --git a/packages/client/components/app/menus/MessageContextMenu.tsx b/packages/client/components/app/menus/MessageContextMenu.tsx index a30d359557..3b67fdd746 100644 --- a/packages/client/components/app/menus/MessageContextMenu.tsx +++ b/packages/client/components/app/menus/MessageContextMenu.tsx @@ -4,6 +4,7 @@ import { Trans } from "@lingui-solid/solid/macro"; import { File, Message } from "stoat.js"; import { useClient, useUser } from "@revolt/client"; +import { useInstance } from "@revolt/instance"; import { CustomEmoji, UnicodeEmoji } from "@revolt/markdown/emoji"; import { useModals } from "@revolt/modal"; import { useState } from "@revolt/state"; @@ -45,6 +46,7 @@ export function MessageContextMenu(props: { }) { const user = useUser(); const state = useState(); + const instance = useInstance(); const client = useClient(); const { openModal, showError } = useModals(); @@ -109,9 +111,11 @@ export function MessageContextMenu(props: { */ function copyMessageLink() { navigator.clipboard.writeText( - `${location.origin}${ - props.message!.server ? `/server/${props.message!.server?.id}` : "" - }/channel/${props.message!.channelId}/${props.message!.id}`, + instance.href( + `${ + props.message!.server ? `/server/${props.message!.server?.id}` : "" + }/channel/${props.message!.channelId}/${props.message!.id}`, + ), ); } diff --git a/packages/client/components/app/menus/UserContextMenu.tsx b/packages/client/components/app/menus/UserContextMenu.tsx index 216c70a0af..25149fea98 100644 --- a/packages/client/components/app/menus/UserContextMenu.tsx +++ b/packages/client/components/app/menus/UserContextMenu.tsx @@ -61,7 +61,7 @@ export function UserContextMenu(props: { * Open direct message channel */ function openDm() { - props.user.openDM().then((channel) => navigate(channel.url)); + props.user.openDM().then((channel) => navigate(channel.path)); props.onClose?.(); } diff --git a/packages/client/components/auth/src/AuthPage.tsx b/packages/client/components/auth/src/AuthPage.tsx index fb97026361..6382a50ac8 100644 --- a/packages/client/components/auth/src/AuthPage.tsx +++ b/packages/client/components/auth/src/AuthPage.tsx @@ -1,14 +1,17 @@ import { BiLogosGithub } from "solid-icons/bi"; -import { JSX } from "solid-js"; +import { JSX, Show } from "solid-js"; import { Trans } from "@lingui-solid/solid/macro"; import { styled } from "styled-system/jsx"; import { Titlebar } from "@revolt/app/interface/desktop/Titlebar"; +import { useClientLifecycle } from "@revolt/client"; +import { State } from "@revolt/client/Controller"; import { useState } from "@revolt/state"; import { IconButton, iconSize } from "@revolt/ui"; import MdDarkMode from "@material-design-icons/svg/filled/dark_mode.svg?component-solid"; +import MdArrowBack from "@material-design-icons/svg/outlined/arrow_back.svg?component-solid"; import background from "./background.jpg"; import { FlowBase } from "./flows/Flow"; @@ -37,9 +40,8 @@ const Base = styled("div", { flexDirection: "column", justifyContent: "space-between", - mdDown: { - padding: "30px 20px", - }, + _tablet: { padding: "30px 20px" }, + _phone: { padding: "10px 5px" }, }, }); @@ -66,7 +68,6 @@ const NavItems = styled("div", { gap: "10px", display: "flex", alignItems: "center", - fontSize: "0.9em", }, variants: { @@ -77,9 +78,8 @@ const NavItems = styled("div", { }, }, stack: { - md: { - flexDirection: "column", - }, + flexDirection: "column", + _tablet: { flexDirection: "row" }, }, }, }, @@ -100,13 +100,14 @@ const LinkWithIcon = styled("a", { */ const Bullet = styled("div", { base: { + display: "none", height: "5px", width: "5px", background: "grey", borderRadius: "50%", - md: { - display: "none", + _tablet: { + display: "block", }, }, }); @@ -115,7 +116,8 @@ const Bullet = styled("div", { * Authentication page */ export function AuthPage(props: { children: JSX.Element }) { - const state = useState(); + const state = useState(), + ctrl = useClientLifecycle(); return (