Add #5's List all supported URLs tooltip #9

merged
opened by aylac.top targeting main from aylac.top/pdsls: appviewhint

when there's no text on the search bar, a little ? button is shown and when clicked a modal with all the urls of apps that can just be pasted and handled are shown

don't have an experience with tailwind, idk how exactly stuff should look, so it was mostly copypasted or gemini organising it. if it could look better tell me and i will do it

Changed files
+60 -2
src
components
utils
+51 -2
src/components/search.tsx
··· 2 2 import { A, useLocation, useNavigate } from "@solidjs/router"; 3 3 import { createResource, createSignal, For, onCleanup, onMount, Show } from "solid-js"; 4 4 import { isTouchDevice } from "../layout"; 5 - import { appHandleLink, appList, AppUrl } from "../utils/app-urls"; 5 + import { appHandleLink, appList, appName, AppUrl } from "../utils/app-urls"; 6 6 import { createDebouncedValue } from "../utils/hooks/debounced"; 7 + import { Modal } from "./modal"; 7 8 8 9 export const [showSearch, setShowSearch] = createSignal(false); 9 10 ··· 113 114 value={input() ?? ""} 114 115 onInput={(e) => setInput(e.currentTarget.value)} 115 116 /> 116 - <Show when={input()}> 117 + <Show when={input()} fallback={ListUrlsTooltip()}> 117 118 <button 118 119 type="button" 119 120 class="flex items-center rounded-lg p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-600 dark:active:bg-neutral-500" ··· 146 147 ); 147 148 }; 148 149 150 + const ListUrlsTooltip = () => { 151 + const [openList, setOpenList] = createSignal(false); 152 + 153 + let urls: Record<string, AppUrl[]> = {}; 154 + for (const [appUrl, appView] of Object.entries(appList)) { 155 + if (!urls[appView]) urls[appView] = [appUrl as AppUrl]; 156 + else urls[appView].push(appUrl as AppUrl); 157 + } 158 + 159 + return ( 160 + <> 161 + <Modal open={openList()} onClose={() => setOpenList(false)}> 162 + <div class="dark:bg-dark-300 dark:shadow-dark-800 absolute top-16 left-[50%] w-[26rem] -translate-x-1/2 rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-4 shadow-md transition-opacity duration-200 dark:border-neutral-700 starting:opacity-0"> 163 + <div class="mb-2 flex items-center gap-1 font-semibold"> 164 + <span class="iconify lucide--link"></span> 165 + <span>Supported URLs</span> 166 + </div> 167 + <div class="mb-2 text-sm text-neutral-500 dark:text-neutral-400"> 168 + Links that will be parsed automatically, as long as all the data necessary is on the 169 + URL. 170 + </div> 171 + <div class="flex flex-col gap-2 text-sm"> 172 + <For each={Object.entries(appName)}> 173 + {([appView, name]) => { 174 + return ( 175 + <div> 176 + <p class="font-semibold">{name}</p> 177 + <div class="grid grid-cols-2 gap-x-4 text-neutral-600 dark:text-neutral-400"> 178 + <For each={urls[appView]}>{(url) => <span>{url}</span>}</For> 179 + </div> 180 + </div> 181 + ); 182 + }} 183 + </For> 184 + </div> 185 + </div> 186 + </Modal> 187 + <button 188 + type="button" 189 + class="flex items-center rounded-lg p-1 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-600 dark:active:bg-neutral-500" 190 + onClick={() => setOpenList(true)} 191 + > 192 + <span class="iconify lucide--help-circle"></span> 193 + </button> 194 + </> 195 + ); 196 + }; 197 + 149 198 export { Search, SearchButton };
+9
src/utils/app-urls.ts
··· 9 9 Linkat, 10 10 } 11 11 12 + export const appName = { 13 + [App.Bluesky]: "Bluesky", 14 + [App.Tangled]: "Tangled", 15 + [App.Whitewind]: "Whitewind", 16 + [App.Frontpage]: "Frontpage", 17 + [App.Pinksea]: "Pinksea", 18 + [App.Linkat]: "Linkat", 19 + }; 20 + 12 21 export const appList: Record<AppUrl, App> = { 13 22 "localhost:19006": App.Bluesky, 14 23 "blacksky.community": App.Bluesky,