atproto explorer

List all supported URLs tooltip

authored by aylac.top and committed by

Tangled e01f8c83 47c0e188

+60 -2
+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" ··· 143 144 </div> 144 145 </Show> 145 146 </form> 147 + ); 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 + </> 146 195 ); 147 196 }; 148 197
+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,