add intro

This commit is contained in:
smolgrrr 2024-08-31 18:18:55 +10:00
parent bbabbc7a5b
commit ebffb2a177
2 changed files with 82 additions and 65 deletions

View File

@ -1,8 +1,6 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, Fragment } from 'react';
import { XMarkIcon } from "@heroicons/react/24/solid"; import { XMarkIcon, ArrowUpOnSquareIcon, PlusCircleIcon } from "@heroicons/react/24/outline";
import { ArrowUpOnSquareIcon, PlusCircleIcon } from '@heroicons/react/24/outline';
import { Dialog, Transition } from '@headlessui/react'; import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from 'react';
declare global { declare global {
interface Navigator { interface Navigator {
@ -10,86 +8,91 @@ declare global {
} }
} }
const AddToHomeScreenPrompt: React.FC = () => { export default function CombinedIntroAndMobile() {
const [showIntro, setShowIntro] = useState(false);
const [inMobileBrowser, setInMobileBrowser] = useState(false); const [inMobileBrowser, setInMobileBrowser] = useState(false);
useEffect(() => { useEffect(() => {
const checkPWA = () => {
// Check if the app is running as a PWA on Android
const isAndroidPWA = window.matchMedia('(display-mode: standalone)').matches ||
window.matchMedia('(display-mode: minimal-ui)').matches;
// Check if the app is running as a PWA on other platforms
const isOtherPWA = window.navigator.standalone;
return !isAndroidPWA && !isOtherPWA;
};
// Function to detect mobile browser
const detectMobileBrowser = () => {
return (
(navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPad/i) ||
navigator.userAgent.match(/iPod/i) ||
navigator.userAgent.match(/Windows Phone/i))
);
};
const timer = setTimeout(() => { const timer = setTimeout(() => {
setInMobileBrowser(Boolean(checkPWA() && detectMobileBrowser())); const hasClosedIntro = localStorage.getItem('hasClosedIntro') !== 'true';
}, 2000); // 3000 milliseconds = 3 seconds setShowIntro(hasClosedIntro);
const checkPWA = () => {
const isAndroidPWA = window.matchMedia('(display-mode: standalone)').matches ||
window.matchMedia('(display-mode: minimal-ui)').matches;
const isOtherPWA = window.navigator.standalone;
return !isAndroidPWA && !isOtherPWA;
};
const detectMobileBrowser = () => {
return /Android|webOS|iPhone|iPad|iPod|Windows Phone/i.test(navigator.userAgent);
};
setInMobileBrowser(checkPWA() && detectMobileBrowser());
}, 2000);
// Cleanup function to clear the timeout if the component unmounts before the timeout finishes
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, []); }, []);
if (!inMobileBrowser) { const handleClose = () => {
return null; setShowIntro(false);
} localStorage.setItem('hasClosedIntro', 'true');
};
if (!showIntro && !inMobileBrowser) return null;
return ( return (
<Transition appear show={inMobileBrowser} as={Fragment}> <Transition appear show={showIntro || inMobileBrowser} as={Fragment}>
<Dialog <Dialog
as="div" as="div"
className="fixed inset-0 z-10 overflow-y-auto" className="fixed inset-0 z-10 overflow-y-auto"
onClose={() => setInMobileBrowser(false)} onClose={handleClose}
> >
<div className="min-h-screen px-4 text-center"> <div className="min-h-screen px-4 text-center">
<Dialog.Overlay className="fixed inset-0 bg-gray-800 opacity-40" /> <Dialog.Overlay className="fixed inset-0 bg-gray-800 opacity-40" />
<span className="inline-block h-screen align-middle" aria-hidden="true">&#8203;</span>
<span <div className="inline-block w-full text-white max-w-md p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-neutral-900 shadow-xl rounded-2xl">
className="inline-block h-screen align-middle" {showIntro && (
aria-hidden="true" <div className="mb-4">
> <h2 className="text-lg font-bold mb-4 flex items-center">
&#8203; Welcome to The Wired
</span> <img src="https://poa.st/emoji/custom/lainsmile.png" className="h-8 ml-2" alt="Lain smile" />
<div className="fixed bottom-0 left-0 right-0 p-4 bg-neutral-900 rounded-lg m-2 border border-neutral-700 shadow-md flex justify-between items-center animate-slide-up"> </h2>
<div className="flex flex-col text-white"> <ul className="list-none space-y-2 text-xs">
<span className="font-semibold">Stay Wired</span> <li>
<p className="text-xs">Add Wired to your home screen for a better experience</p> {'>'} Here your anonymous posts are distributed among a series of independent <a className="underline" href="https://github.com/nostr-protocol/nostr" target="_blank" rel="noopener noreferrer">NOSTR</a> relay servers,
<ul className="list-none mt-2 text-sm"> which means they are highly resistant to censorship and moderation.
<li> </li>
<div className="flex items-center"> <li>
<span className="mr-2">{'>'}</span> Click on <ArrowUpOnSquareIcon className="h-6 w-6 ml-1 text-blue-500" /> <span className="font-semibold text-blue-500">Share</span> {'>'} Each post must use Proof-of-Work to reduce spam and noise. Your note's ID is a hash of the note,
and this hashing is done repeatedly with a nonce until it starts with multiple leading zeros,
which approximates the work done to generate the note.
</li>
</ul>
</div> </div>
</li> )}
<li> {inMobileBrowser && (
<div className="flex items-center"> <div className="mt-4">
<span className="mr-2">{'>'}</span> Click <PlusCircleIcon className="h-6 w-6 ml-1 text-blue-500" /> <span className="font-semibold text-blue-500">Add to Home Screen</span> <p className="text-xs mb-2">Add Wired to your home screen for a better experience</p>
<ul className="list-none text-sm">
<li className="flex items-center">
<span className="mr-2">{'>'}</span> Click on <ArrowUpOnSquareIcon className="h-6 w-6 ml-1 text-blue-500" /> <span className="font-semibold text-blue-500">Share</span>
</li>
<li className="flex items-center">
<span className="mr-2">{'>'}</span> Click <PlusCircleIcon className="h-6 w-6 ml-1 text-blue-500" /> <span className="font-semibold text-blue-500">Add to Home Screen</span>
</li>
</ul>
</div> </div>
</li> )}
</ul> <button
</div> className="absolute top-2 right-2 text-neutral-400 hover:text-neutral-200"
<button className="absolute top-2 right-2" onClick={() => {setInMobileBrowser(!inMobileBrowser);}}> onClick={handleClose}
<XMarkIcon className="h-6 w-6 text-white" /> >
</button> <XMarkIcon className="h-6 w-6" />
</div> </button>
</div>
</div> </div>
</Dialog> </Dialog>
</Transition> </Transition>
); );
}; }
export default AddToHomeScreenPrompt;

View File

@ -25,6 +25,20 @@ const colorCombos = [
"from-rose-300 to-pink-700", "from-rose-300 to-pink-700",
"from-violet-300 to-purple-700", "from-violet-300 to-purple-700",
"from-sky-300 to-cyan-700", "from-sky-300 to-cyan-700",
"from-fuchsia-300 to-purple-700",
"from-emerald-300 to-teal-700",
"from-slate-300 to-gray-700",
"from-zinc-300 to-slate-700",
"from-stone-300 to-zinc-700",
"from-neutral-300 to-stone-700",
"from-red-300 to-pink-700",
"from-orange-300 to-amber-700",
"from-yellow-300 to-lime-700",
"from-green-300 to-emerald-700",
"from-teal-300 to-cyan-700",
"from-blue-300 to-sky-700",
"from-indigo-300 to-blue-700",
"from-purple-300 to-indigo-700",
]; ];
export const getIconFromHash = (id: string): string => { export const getIconFromHash = (id: string): string => {