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 { XMarkIcon } from "@heroicons/react/24/solid";
import { ArrowUpOnSquareIcon, PlusCircleIcon } from '@heroicons/react/24/outline';
import React, { useState, useEffect, Fragment } from 'react';
import { XMarkIcon, ArrowUpOnSquareIcon, PlusCircleIcon } from "@heroicons/react/24/outline";
import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from 'react';
declare global {
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);
useEffect(() => {
const timer = setTimeout(() => {
const hasClosedIntro = localStorage.getItem('hasClosedIntro') !== 'true';
setShowIntro(hasClosedIntro);
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))
);
return /Android|webOS|iPhone|iPad|iPod|Windows Phone/i.test(navigator.userAgent);
};
const timer = setTimeout(() => {
setInMobileBrowser(Boolean(checkPWA() && detectMobileBrowser()));
}, 2000); // 3000 milliseconds = 3 seconds
setInMobileBrowser(checkPWA() && detectMobileBrowser());
}, 2000);
// Cleanup function to clear the timeout if the component unmounts before the timeout finishes
return () => clearTimeout(timer);
}, []);
if (!inMobileBrowser) {
return null;
}
const handleClose = () => {
setShowIntro(false);
localStorage.setItem('hasClosedIntro', 'true');
};
if (!showIntro && !inMobileBrowser) return null;
return (
<Transition appear show={inMobileBrowser} as={Fragment}>
<Transition appear show={showIntro || inMobileBrowser} as={Fragment}>
<Dialog
as="div"
className="fixed inset-0 z-10 overflow-y-auto"
onClose={() => setInMobileBrowser(false)}
onClose={handleClose}
>
<div className="min-h-screen px-4 text-center">
<Dialog.Overlay className="fixed inset-0 bg-gray-800 opacity-40" />
<span
className="inline-block h-screen align-middle"
aria-hidden="true"
>
&#8203;
</span>
<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">
<div className="flex flex-col text-white">
<span className="font-semibold">Stay Wired</span>
<p className="text-xs">Add Wired to your home screen for a better experience</p>
<ul className="list-none mt-2 text-sm">
<span className="inline-block h-screen align-middle" aria-hidden="true">&#8203;</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">
{showIntro && (
<div className="mb-4">
<h2 className="text-lg font-bold mb-4 flex items-center">
Welcome to The Wired
<img src="https://poa.st/emoji/custom/lainsmile.png" className="h-8 ml-2" alt="Lain smile" />
</h2>
<ul className="list-none space-y-2 text-xs">
<li>
<div 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>
</div>
{'>'} 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,
which means they are highly resistant to censorship and moderation.
</li>
<li>
<div 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>
</div>
{'>'} 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>
<button className="absolute top-2 right-2" onClick={() => {setInMobileBrowser(!inMobileBrowser);}}>
<XMarkIcon className="h-6 w-6 text-white" />
)}
{inMobileBrowser && (
<div className="mt-4">
<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>
)}
<button
className="absolute top-2 right-2 text-neutral-400 hover:text-neutral-200"
onClick={handleClose}
>
<XMarkIcon className="h-6 w-6" />
</button>
</div>
</div>
</Dialog>
</Transition>
);
};
export default AddToHomeScreenPrompt;
}

View File

@ -25,6 +25,20 @@ const colorCombos = [
"from-rose-300 to-pink-700",
"from-violet-300 to-purple-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 => {