The weeb for the next gen discord boat - Wamellow wamellow.com
bot discord
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor: guild list animation (#44)

authored by

Luna Seemann and committed by
GitHub
534a62d5 cf3c7fea

+30 -34
+27 -34
app/profile/page.tsx
··· 8 8 import { useApi } from "@/lib/api/hook"; 9 9 import type { ApiV1UsersMeGuildsGetResponse } from "@/typings"; 10 10 import { cn } from "@/utils/cn"; 11 + import type { Variants } from "motion/react"; 11 12 import { motion } from "motion/react"; 12 13 import Link from "next/link"; 13 14 import { useSearchParams } from "next/navigation"; ··· 16 17 17 18 const MAX_GUILDS = 20 as const; 18 19 19 - const springAnimation = { 20 + const springAnimation: Variants = { 20 21 hidden: { y: 20, opacity: 0 }, 21 - visible: { 22 + visible: (i: number) => ({ 22 23 y: 0, 23 24 opacity: 1, 24 25 transition: { 26 + delay: i * 0.1, 25 27 type: "spring", 26 - bounce: 0.4, 27 - duration: 0.7 28 + bounce: 0.6, 29 + duration: 0.8 28 30 } 29 - } 30 - } as const; 31 + }) 32 + }; 31 33 32 34 export default function Home() { 33 35 const [search, setSearch] = useState<string>(""); ··· 55 57 return (<div className="flex flex-col w-full"> 56 58 <div className="flex flex-col md:flex-row md:justify-between gap-2"> 57 59 <ControlledInput 60 + autoFocus 58 61 thin 59 62 value={search} 60 63 setValue={setSearch} ··· 92 95 93 96 {isLoading ? ( 94 97 <div className="grid grid-cols-1 gap-3.5 w-full mt-3 lg:grid-cols-3 md:grid-cols-2"> 95 - {Array.from({ length: 1 }).map((_, i) => ( 96 - <Skeleton key={i} className="h-22 rounded-xl" style={{ opacity: 1 / i }} /> 97 - ))} 98 + <Skeleton className="h-22 rounded-xl" /> 98 99 </div> 99 100 ) : ( 100 - <motion.ul 101 - variants={{ 102 - hidden: { opacity: 1, scale: 0 }, 103 - visible: { 104 - opacity: 1, 105 - scale: 1, 106 - transition: { 107 - delayChildren: size > 20 ? 0.2 : 0.3, 108 - staggerChildren: size > 20 ? 0.1 : 0.2 109 - } 110 - } 111 - }} 112 - initial={(dataUpdatedAt + 1_000) < time ? "visible" : "hidden"} 113 - animate="visible" 114 - className="grid grid-cols-1 gap-3.5 w-full mt-3 lg:grid-cols-3 md:grid-cols-2" 115 - > 116 - {guilds.map((guild) => ( 101 + <ul className="grid grid-cols-1 gap-3.5 w-full mt-3 lg:grid-cols-3 md:grid-cols-2"> 102 + {guilds.map((guild, index) => ( 117 103 <Guild 118 104 key={"guild-" + guild.id} 119 105 {...guild} 120 - isHugeGuildList={isHuge} 106 + lazy={isHuge} 107 + index={index} 108 + animate={(dataUpdatedAt + 1_000) > time} 121 109 /> 122 110 )) 123 111 } 124 - </motion.ul> 112 + </ul> 125 113 )} 126 114 127 115 {isHuge && ( ··· 157 145 name, 158 146 icon, 159 147 bot: hasBotInvited, 160 - isHugeGuildList 161 - }: ApiV1UsersMeGuildsGetResponse & { isHugeGuildList: boolean; }) { 148 + lazy, 149 + index, 150 + animate 151 + }: ApiV1UsersMeGuildsGetResponse & { lazy: boolean; index: number; animate: boolean; }) { 162 152 return ( 163 153 <motion.li 154 + custom={index} 155 + initial={animate ? "hidden" : "visible"} 156 + animate="visible" 164 157 className={cn( 165 - "dark:bg-wamellow bg-wamellow-100 p-3.5 flex items-center rounded-xl drop-shadow-md overflow-hidden relative duration-100 outline-violet-500 hover:outline-solid group/card", 158 + "dark:bg-wamellow bg-wamellow-100 p-3.5 flex items-center rounded-xl drop-shadow-md overflow-hidden relative outline-violet-500 hover:outline-solid group/card opacity-0", 166 159 !hasBotInvited && "saturate-50 brightness-50" 167 160 )} 168 161 variants={springAnimation} 169 162 > 170 163 <ImageReduceMotion 171 164 alt="" 172 - className="absolute top-[-48px] left-0 w-full z-0 blur-xl opacity-30 pointer-events-none" 165 + className="absolute -top-12 left-0 w-full z-0 blur-xl opacity-30 pointer-events-none" 173 166 size={16} 174 167 url={`https://cdn.discordapp.com/icons/${id}/${icon}`} 175 168 forceStatic 176 - lazy={isHugeGuildList} 169 + lazy={lazy} 177 170 /> 178 171 179 172 <ImageReduceMotion ··· 181 174 className="rounded-lg size-15 z-1 relative drop-shadow-md" 182 175 size={56} 183 176 url={`https://cdn.discordapp.com/icons/${id}/${icon}`} 184 - lazy={isHugeGuildList} 177 + lazy={lazy} 185 178 /> 186 179 187 180 <div className="ml-3 text-sm relative bottom-0.5">
+3
components/inputs/controlled-input.tsx
··· 20 20 multiline?: boolean; 21 21 type?: string; 22 22 thin?: boolean; 23 + autoFocus?: boolean; 23 24 24 25 /** For use with JSON state - specifies which key to update */ 25 26 dataName?: string; ··· 41 42 multiline, 42 43 type, 43 44 thin, 45 + autoFocus, 44 46 dataName 45 47 }: Props) { 46 48 // Get actual value from JSON if dataName is provided ··· 108 110 disabled={disabled} 109 111 maxLength={max} 110 112 type={type} 113 + autoFocus={autoFocus} 111 114 /> 112 115 )} 113 116