added pwa support
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ type AppConfig = {
|
||||
};
|
||||
|
||||
export const appConfig: AppConfig = {
|
||||
name: "Betterwise",
|
||||
name: "Bettesplit",
|
||||
navigator: [
|
||||
{
|
||||
name: "Home",
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import AddFriendDrawer from "@/app/_components/friend/add-friend-drawer";
|
||||
import FriendList from "@/app/_components/friend/friend-list";
|
||||
import Header from "@/components/header";
|
||||
import { auth } from "@/server/auth";
|
||||
import { api, HydrateClient } from "@/trpc/server";
|
||||
import React from "react";
|
||||
|
||||
export default async function Page() {
|
||||
void api.friend.getAll.prefetch();
|
||||
const session = await auth();
|
||||
if (session?.user) void api.friend.getAll.prefetch();
|
||||
|
||||
return (
|
||||
<HydrateClient>
|
||||
|
||||
@@ -4,13 +4,14 @@ import React from "react";
|
||||
export default function FriendRequestButton({}: {}) {
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
{/* <Button
|
||||
variant={requestedBy === "me" ? "destructive" : "outline"}
|
||||
className="ml-auto"
|
||||
size="sm"
|
||||
>
|
||||
{requestedBy === "me" ? "Cancel" : "Accept"}
|
||||
</Button>
|
||||
</Button> */}
|
||||
friendRequestButton
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// "use client";
|
||||
// import React, { useEffect, useState } from "react";
|
||||
// export function usePwaInstallStatus() {
|
||||
// const [isStandalone, setIsStandalone] = useState(false);
|
||||
// const [isIOS, setIsIOS] = useState(false);
|
||||
// const [isAndroid, setIsAndroid] = useState(false);
|
||||
|
||||
// useEffect(() => {
|
||||
// const userAgent =
|
||||
// navigator.userAgent || navigator.vendor || (window as any).opera;
|
||||
|
||||
// // iOS detection
|
||||
// const iOS = /iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream;
|
||||
// setIsIOS(iOS);
|
||||
|
||||
// // Android detection
|
||||
// const android = /android/i.test(userAgent);
|
||||
// setIsAndroid(android);
|
||||
|
||||
// // PWA "standalone" mode detection (works for both iOS & Android)
|
||||
// const isInStandaloneMode =
|
||||
// window.matchMedia("(display-mode: standalone)").matches ||
|
||||
// (navigator as any).standalone === true; // for iOS Safari
|
||||
|
||||
// setIsStandalone(isInStandaloneMode);
|
||||
// }, []);
|
||||
|
||||
// return { isIOS, isAndroid, isStandalone };
|
||||
// }
|
||||
|
||||
// function InstallPrompt() {
|
||||
// const { isIOS, isAndroid, isStandalone } = usePwaInstallStatus();
|
||||
// const [deferredPrompt, setDeferredPrompt] = useState<any>(null);
|
||||
|
||||
// useEffect(() => {
|
||||
// const handler = (e: any) => {
|
||||
// e.preventDefault();
|
||||
// setDeferredPrompt(e);
|
||||
// };
|
||||
|
||||
// window.addEventListener("beforeinstallprompt", handler);
|
||||
|
||||
// return () => {
|
||||
// window.removeEventListener("beforeinstallprompt", handler);
|
||||
// };
|
||||
// }, []);
|
||||
|
||||
// const handleInstallClick = () => {
|
||||
// console.log("install clicked");
|
||||
|
||||
// if (deferredPrompt) {
|
||||
// deferredPrompt.prompt();
|
||||
// deferredPrompt.userChoice.then((choiceResult: any) => {
|
||||
// if (choiceResult.outcome === "accepted") {
|
||||
// console.log("User accepted the A2HS prompt");
|
||||
// } else {
|
||||
// console.log("User dismissed the A2HS prompt");
|
||||
// }
|
||||
// setDeferredPrompt(null);
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
// if (isStandalone) {
|
||||
// return null; // Already running as a PWA, no need to show install prompt
|
||||
// }
|
||||
|
||||
// return (
|
||||
// <div className="absolute w-full h-20 z-50 bg-red-500 left-0 flex items-center justify-center right-0 bottom-0 text-white">
|
||||
// {isIOS && <p>Tap "Share" and "Add to Home Screen" to install the app.</p>}
|
||||
// {isAndroid && <button onClick={handleInstallClick}>Install App</button>}
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
// export default function PWAWrapper({
|
||||
// children,
|
||||
// }: {
|
||||
// children: React.ReactNode;
|
||||
// }) {
|
||||
// return (
|
||||
// <>
|
||||
// <InstallPrompt />
|
||||
// {children}
|
||||
// </>
|
||||
// );
|
||||
// }
|
||||
@@ -5,6 +5,7 @@ import { Geist } from "next/font/google";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { TRPCReactProvider } from "@/trpc/react";
|
||||
import { ThemeProvider } from "@/components/theme-provider";
|
||||
// import PWAWrapper from "./_components/install-prompt";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create T3 App",
|
||||
@@ -30,6 +31,8 @@ export default function RootLayout({
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
{/* <PWAWrapper>
|
||||
</PWAWrapper> */}
|
||||
{children}
|
||||
<Toaster position="top-center" />
|
||||
</ThemeProvider>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { appConfig } from "@/app.config";
|
||||
import type { MetadataRoute } from "next";
|
||||
|
||||
export default function manifest(): MetadataRoute.Manifest {
|
||||
return {
|
||||
name: appConfig.name,
|
||||
short_name: "NextPWA",
|
||||
description: "A Progressive Web App built with Next.js",
|
||||
start_url: "/",
|
||||
display: "standalone",
|
||||
background_color: "#ffffff",
|
||||
theme_color: "#000000",
|
||||
icons: [
|
||||
{
|
||||
src: "/icon-192x192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: "/icon-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -15,7 +15,7 @@ function NavLink({ href, name, icon }: NavLink) {
|
||||
asChild
|
||||
variant={"ghost"}
|
||||
className={cn(
|
||||
"p-2 size-12 text-muted-foreground/75 flex flex-col gap-2 ",
|
||||
"p-2 size-12 text-muted-foreground/75 flex flex-col gap-2 hover:bg-transparent dark:hover:bg-transparent ",
|
||||
active && "text-foreground "
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import { useTheme } from "next-themes"
|
||||
import { Toaster as Sonner, ToasterProps } from "sonner"
|
||||
import { useTheme } from "next-themes";
|
||||
import { Toaster as Sonner, type ToasterProps } from "sonner";
|
||||
|
||||
const Toaster = ({ ...props }: ToasterProps) => {
|
||||
const { theme = "system" } = useTheme()
|
||||
const { theme = "system" } = useTheme();
|
||||
|
||||
return (
|
||||
<Sonner
|
||||
@@ -19,7 +19,7 @@ const Toaster = ({ ...props }: ToasterProps) => {
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export { Toaster }
|
||||
export { Toaster };
|
||||
|
||||
Vendored
@@ -38,6 +38,7 @@ declare module "next-auth" {
|
||||
* @see https://next-auth.js.org/configuration/options
|
||||
*/
|
||||
export const authConfig = {
|
||||
trustHost: true,
|
||||
providers: [
|
||||
DiscordProvider,
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user