mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-13 04:45:19 +00:00
Add mobile unsupported splash screne
This commit is contained in:
parent
7ce10672e1
commit
b9352345a3
8 changed files with 84 additions and 13 deletions
|
|
@ -118,6 +118,7 @@
|
|||
"pretty-bytes": "^6.1.1",
|
||||
"psl": "^1.15.0",
|
||||
"react": "^18",
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18",
|
||||
"react-hook-form": "^7.53.0",
|
||||
"react-hotkeys-hook": "^4.5.1",
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { GithubConnectionConfig, GitlabConnectionConfig, GiteaConnectionConfig,
|
|||
import { encrypt } from "@sourcebot/crypto"
|
||||
import { getConnection } from "./data/connection";
|
||||
import { ConnectionSyncStatus, Prisma, OrgRole, RepoIndexingStatus, StripeSubscriptionStatus } from "@sourcebot/db";
|
||||
import { headers } from "next/headers"
|
||||
import { cookies, headers } from "next/headers"
|
||||
import { getStripe } from "@/lib/stripe"
|
||||
import { getUser } from "@/data/user";
|
||||
import { Session } from "next-auth";
|
||||
|
|
@ -26,6 +26,7 @@ import InviteUserEmail from "./emails/inviteUserEmail";
|
|||
import { createTransport } from "nodemailer";
|
||||
import { repositoryQuerySchema } from "./lib/schemas";
|
||||
import { RepositoryQuery } from "./lib/types";
|
||||
import { MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME } from "./lib/constants";
|
||||
|
||||
const ajv = new Ajv({
|
||||
validateFormats: false,
|
||||
|
|
@ -1231,6 +1232,10 @@ export const getOrgInvites = async (domain: string) =>
|
|||
})
|
||||
);
|
||||
|
||||
export const dismissMobileUnsupportedSplashScreen = async () => {
|
||||
await cookies().set(MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME, 'true');
|
||||
}
|
||||
|
||||
|
||||
////// Helpers ///////
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
'use client';
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { TriangleAlert } from "lucide-react";
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { dismissMobileUnsupportedSplashScreen } from "@/actions";
|
||||
import useCaptureEvent from "@/hooks/useCaptureEvent";
|
||||
|
||||
export const MobileUnsupportedSplashScreen = () => {
|
||||
const captureEvent = useCaptureEvent();
|
||||
|
||||
useEffect(() => {
|
||||
captureEvent('wa_mobile_unsupported_splash_screen_displayed', {});
|
||||
}, [captureEvent]);
|
||||
|
||||
const onDismissed = useCallback(() => {
|
||||
dismissMobileUnsupportedSplashScreen();
|
||||
captureEvent('wa_mobile_unsupported_splash_screen_dismissed', {});
|
||||
}, [captureEvent]);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center p-2 min-h-screen bg-backgroundSecondary">
|
||||
<Card className="flex flex-col items-center text-center mb-10 p-4 max-w-sm">
|
||||
<TriangleAlert className="w-10 h-10 mb-4 text-yellow-600/90 dark:text-yellow-300/90" />
|
||||
<div className="text-2xl font-semibold flex items-center mb-2">
|
||||
Mobile is not supported.
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground mb-8">
|
||||
Sourcebot on mobile is still a work in progress. Please use a desktop computer to get the best experience.
|
||||
</p>
|
||||
<Button
|
||||
className="w-full"
|
||||
variant="outline"
|
||||
onClick={onDismissed}
|
||||
>
|
||||
Continue anyway
|
||||
</Button>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -6,6 +6,10 @@ import { isServiceError } from "@/lib/utils";
|
|||
import { OnboardGuard } from "./components/onboardGuard";
|
||||
import { fetchSubscription } from "@/actions";
|
||||
import { UpgradeGuard } from "./components/upgradeGuard";
|
||||
import { cookies, headers } from "next/headers";
|
||||
import { getSelectorsByUserAgent } from "react-device-detect";
|
||||
import { MobileUnsupportedSplashScreen } from "./components/mobileUnsupportedSplashScreen";
|
||||
import { MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME } from "@/lib/constants";
|
||||
|
||||
interface LayoutProps {
|
||||
children: React.ReactNode,
|
||||
|
|
@ -65,5 +69,15 @@ export default async function Layout({
|
|||
)
|
||||
}
|
||||
|
||||
const headersList = await headers();
|
||||
const cookieStore = await cookies()
|
||||
const userAgent = headersList.get('user-agent');
|
||||
const { isMobile } = getSelectorsByUserAgent(userAgent ?? '');
|
||||
|
||||
if (isMobile && !cookieStore.has(MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME)) {
|
||||
return (
|
||||
<MobileUnsupportedSplashScreen />
|
||||
)
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
|
@ -24,15 +24,15 @@ export default async function Upgrade({ params: { domain } }: { params: { domain
|
|||
const isTrialing = !isServiceError(subscription) ? subscription.status === "trialing" : false;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center pt-12 min-h-screen bg-backgroundSecondary relative">
|
||||
<div className="flex flex-col items-center pt-12 px-4 sm:px-12 min-h-screen bg-backgroundSecondary relative">
|
||||
{isTrialing && (
|
||||
<Link href={`/${domain}`} className="text-sm text-muted-foreground mb-5 absolute top-0 left-0 p-12">
|
||||
<Link href={`/${domain}`} className="text-sm text-muted-foreground mb-5 absolute top-0 left-0 p-4 sm:p-12">
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<ArrowLeftIcon className="w-4 h-4" /> Return to dashboard
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
<LogoutEscapeHatch className="absolute top-0 right-0 p-12" />
|
||||
<LogoutEscapeHatch className="absolute top-0 right-0 p-4 sm:p-12" />
|
||||
<div className="flex flex-col items-center">
|
||||
<SourcebotLogo
|
||||
className="h-16 mb-2"
|
||||
|
|
|
|||
|
|
@ -21,4 +21,6 @@ export const TEAM_FEATURES = [
|
|||
"Public and private repos supported.",
|
||||
"Create shareable links to code snippets.",
|
||||
"Powerful regex and symbol search",
|
||||
]
|
||||
]
|
||||
|
||||
export const MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME = 'sb.mobile-unsupported-splash-screen-dismissed';
|
||||
|
|
@ -219,6 +219,8 @@ export type PosthogEventMap = {
|
|||
wa_login_with_magic_link: {},
|
||||
wa_login_with_credentials: {},
|
||||
//////////////////////////////////////////////////////////////////
|
||||
wa_mobile_unsupported_splash_screen_dismissed: {},
|
||||
wa_mobile_unsupported_splash_screen_displayed: {},
|
||||
}
|
||||
|
||||
export type PosthogEvent = keyof PosthogEventMap;
|
||||
21
yarn.lock
21
yarn.lock
|
|
@ -7716,6 +7716,13 @@ raw-body@2.5.2:
|
|||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
react-device-detect@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.npmjs.org/react-device-detect/-/react-device-detect-2.2.3.tgz#97a7ae767cdd004e7c3578260f48cf70c036e7ca"
|
||||
integrity sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==
|
||||
dependencies:
|
||||
ua-parser-js "^1.0.33"
|
||||
|
||||
react-dom@^18:
|
||||
version "18.3.1"
|
||||
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz"
|
||||
|
|
@ -8616,14 +8623,7 @@ stringify-entities@^4.0.0:
|
|||
character-entities-html4 "^2.0.0"
|
||||
character-entities-legacy "^3.0.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
|
|
@ -9030,6 +9030,11 @@ typescript@^5.7.3:
|
|||
resolved "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz"
|
||||
integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==
|
||||
|
||||
ua-parser-js@^1.0.33:
|
||||
version "1.0.40"
|
||||
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.40.tgz#ac6aff4fd8ea3e794a6aa743ec9c2fc29e75b675"
|
||||
integrity sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==
|
||||
|
||||
uc.micro@^2.0.0, uc.micro@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz"
|
||||
|
|
|
|||
Loading…
Reference in a new issue