damus.io

damus.io website
git clone git://jb55.com/damus.io
Log | Files | Refs | README | LICENSE

WhatIsNotedeck.tsx (10393B)


      1 import { Onest } from 'next/font/google'
      2 import { FormattedMessage, useIntl } from "react-intl";
      3 import { motion } from "framer-motion";
      4 import { RoundedContainerWithGradientBorder } from "@/components/ui/RoundedContainerWithGradientBorder";
      5 import { cn } from "@/lib/utils";
      6 import { Columns, Eye, Film, Gauge, Globe, Joystick, KeyRound, Mail, Scale, Search, Settings2, ThumbsUp, Upload, Wallet, Zap, ArrowLeftRightIcon } from "lucide-react";
      7 import { MeshGradient3 } from "@/components/effects/MeshGradient.3";
      8 import { MarkdownView } from '@/components/ui/MarkdownView';
      9 import { Item, ItemSection } from './ItemSection';
     10 import Markdown from 'react-markdown';
     11 
     12 const onest = Onest({ subsets: ['latin'] })
     13 
     14 export function WhatIsNotedeck({ className }: { className?: string }) {
     15     const intl = useIntl()
     16 
     17     const list = {
     18       visible: {
     19         opacity: 1,
     20         transition: {
     21           when: "beforeChildren",
     22           staggerChildren: 2,
     23         },
     24       },
     25       hidden: {
     26         opacity: 0,
     27         transition: {
     28           when: "afterChildren",
     29         },
     30       },
     31     }
     32 
     33     const item = {
     34       visible: {
     35         opacity: 1
     36       },
     37       hidden: {
     38         opacity: 0
     39       },
     40     }
     41 
     42     const items: Item[] = [
     43         {
     44           icon: <Eye className="h-12 w-12 text-white opacity-80"/>,
     45           headline: intl.formatMessage({ id: "notedeck.feature.customization.name", defaultMessage: "Powerful Views" }),
     46           description: intl.formatMessage({ id: "notedeck.feature.customization.description", defaultMessage: "Add profile, hashtag, and notification columns of any nostr public or private key. Which means you can see the nostr landscape through other peoples' eyes" }),
     47         },
     48         {
     49           icon: <Gauge className="h-12 w-12 text-white opacity-80"/>,
     50           headline: intl.formatMessage({ id: "notedeck.feature.speed.name", defaultMessage: "Speed" }),
     51           description: intl.formatMessage({ id: "notedeck.feature.speed.description", defaultMessage: "The fastest nostr client. Built from the ground up with an ultra-fast database made exclusively for nostr, leveraging several state-of-the-art performance techniques not available on web clients" }),
     52         },
     53         {
     54           icon: <ArrowLeftRightIcon className="h-12 w-12 text-white opacity-80"/>,
     55           headline: intl.formatMessage({ id: "notedeck.feature.availability.name", defaultMessage: "Switch Between Accounts" }),
     56           description: intl.formatMessage({ id: "notedeck.feature.availability.description", defaultMessage: "Nostriches can also switch between multiple accounts quickly and easily, drastically improving personal and business use cases" }),
     57         },
     58     ]
     59 
     60     return (<>
     61       <div id="introducing" className={cn("bg-black overflow-hidden relative", className)}>
     62           <div className="container mx-auto px-6 pb-32 pt-20">
     63               <div className="flex flex-col items-center justify-center mt-32 lg:mt-16">
     64                   <div className="relative mb-16 flex flex-col items-center">
     65                       <motion.h2
     66                           className={cn("mt-6 text-3xl sm:text-4xl md:text-5xl text-center text-transparent bg-clip-text pb-6 font-semibold whitespace-pre-line max-w-4xl tracking-wide leading-relaxed", onest.className)}
     67                           style={{
     68                               backgroundImage: "linear-gradient(to right, #ffffff -100%, #ffffff -40%, #2D175B 100%)",
     69                               opacity: 0,
     70                           }}
     71                           animate={{
     72                               backgroundImage: "linear-gradient(to right, #ffffff 0%, #ffffff 60%, #2D175B 150%)",
     73                               transition: { duration: 2 },
     74                               opacity: 1
     75                           }}
     76                       >
     77                         {intl.formatMessage({ id: "notedeck.what-is.headline", defaultMessage: "Introducing Notedeck" })}
     78                       </motion.h2>
     79                       <motion.div
     80                         initial="hidden"
     81                         whileInView="visible"
     82                         transition={{ duration: 1 }}
     83                         variants={list}
     84                         viewport={{ once: true }}
     85                       >
     86                         <motion.div
     87                           className={cn("text-white/60 text-4xl leading-relaxed text-left max-w-4xl my-32 break-keep")}
     88                           variants={item}
     89                           transition={{ duration: 1 }}
     90                         >
     91                           <SpecialMarkdownView>
     92                             {intl.formatMessage({
     93                               id: "notedeck.what-is.description1",
     94                               defaultMessage: "**Nostr is the future of social media** and Notedeck is our latest innovation towards the **future of nostr**.\n\n"
     95                             })}
     96                           </SpecialMarkdownView>
     97                         </motion.div>
     98                         <motion.div
     99                           className={cn("text-white/60 text-4xl leading-relaxed text-left max-w-4xl my-32 break-keep")}
    100                           variants={item}
    101                           transition={{ duration: 1 }}
    102                         >
    103                           <SpecialMarkdownView>
    104                             {intl.formatMessage({
    105                               id: "notedeck.what-is.description2",
    106                               defaultMessage: "A **lightning fast native app** that allows you to explore the nostr social network in a **completely new way**! Notedeck includes several power features to both personal and business use cases, including:"
    107                             })}
    108                           </SpecialMarkdownView>
    109                         </motion.div>
    110                         {(intl.locale != "ja" || process.env.FORCE_LOAD_ALL_JA_SECTIONS) && (
    111                             <motion.div
    112                               className="flex flex-wrap gap-x-8 gap-y-16 items-stretch justify-center mt-28 mb-56"
    113                               variants={item}
    114                             >
    115                                 {items.map((item, index) => (
    116                                     <ItemView key={index} item={item} index={index} />
    117                                 ))}
    118                             </motion.div>
    119                         )}
    120                         <motion.div
    121                           className={cn("text-white/60 text-4xl leading-relaxed text-left max-w-4xl my-32 break-keep")}
    122                           variants={item}
    123                           transition={{ duration: 1 }}
    124                         >
    125                           <SpecialMarkdownView>
    126                             {intl.formatMessage({
    127                               id: "notedeck.what-is.description3",
    128                               defaultMessage: "This isn't a web app and it's not just \"another\" social client. This is nostr **like you've never seen it before!**\n\nNotedeck works on **Linux**, **macOS**, and **Windows** on day one. An Android version will be added in 2025, along with iOS and iPadOS eventually.\n\nFuture nostr apps **will run on Notedeck in 2025.**\n\nAn early Notedeck Alpha version is available **today** to our paid [Purple](/purple) subscribers."
    129                             })}
    130                           </SpecialMarkdownView>
    131                         </motion.div>
    132                       </motion.div>
    133                   </div>
    134               </div>
    135           </div>
    136       </div>
    137     </>)
    138 }
    139 
    140 interface ItemViewProps {
    141   item: Item,
    142   index: number
    143 }
    144 
    145 function ItemView({ item, index }: ItemViewProps) {
    146   return (
    147     <div key={index} className="w-72 flex flex-col items-start justify-start">
    148         <div className="flex justify-between w-full items-start">
    149           {item.icon}
    150           {item.badgeText && (
    151             <div className={cn("py-1 px-2 bg-orange-500/30 text-orange-200 rounded-lg", item.badgeClassName)}>
    152               {item.badgeText}
    153             </div>
    154           )}
    155         </div>
    156         <h3 className="text-xl font-semibold text-transparent bg-clip-text bg-gradient-to-br text-white text-left text-normal mt-6">
    157           {item.headline}
    158         </h3>
    159         <p className="text-white/80 text-left text-normal mt-4">
    160           {item.description}
    161         </p>
    162     </div>
    163   )
    164 }
    165 
    166 function SpecialMarkdownView({ children, className }: { children?: string | null | undefined, className?: string }) {
    167 
    168   const container = {
    169     hidden: { opacity: 0 },
    170     show: {
    171       opacity: 1,
    172       transition: {
    173         delayChildren: 1,
    174         staggerChildren: 1
    175       }
    176     }
    177   }
    178 
    179   const item = {
    180     hidden: { opacity: 0.6 },
    181     show: { opacity: 1 }
    182   }
    183 
    184   return (
    185     <motion.div
    186       initial="hidden"
    187       whileInView="show"
    188       transition={{ duration: 0.5 }}
    189       variants={container}
    190       className={className}
    191     >
    192       <Markdown components={{
    193         h1: ({node, ...props}) => <h1 className="opacity-90 font-bold text-6xl mb-6" {...props} />,
    194         h2: ({node, ...props}) => <h2 className="opacity-90 font-bold text-4xl mb-4" {...props} />,
    195         h3: ({node, ...props}) => <h3 className="opacity-90 font-bold text-2xl" {...props} />,
    196         ul: ({node, ...props}) => <ul className="opacity-80 list-disc list-inside mb-5" {...props} />,
    197         ol: ({node, ...props}) => <ol className="opacity-80 list-decimal list-inside mb-5" {...props} />,
    198         li: ({node, ...props}) => <li className="opacity-80 m-1" {...props} />,
    199         em: ({node, ...props}) => <i className="italic" {...props} />,
    200         // @ts-ignore
    201         strong: ({node, ...props}) => <motion.strong
    202           variants={item}
    203           className="font-bold text-white"
    204           {...props}
    205         />,
    206         p: ({node, ...props}) => <p className="opacity-80 mb-4" {...props} />,
    207         // @ts-ignore
    208         a: ({node, ...props}) => <motion.a
    209           variants={item}
    210           className="text-white font-bold underline"
    211           target="_blank"
    212           {...props}
    213         />,
    214         pre: ({node, ...props}) => <pre className="my-2 bg-white/10 overflow-scroll p-3 rounded-lg font-mono" {...props} />,
    215         code: ({node, ...props}) => {
    216           return (<code className="my-2 bg-white/10 overflow-scroll p-1 font-mono rounded-sm" {...props} />)
    217         },
    218       }} className={className}>{children}</Markdown>
    219     </motion.div>
    220   )
    221 }