objective categorical abstract machine language personal data server
65
fork

Configure Feed

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

at main 123 lines 4.0 kB view raw
1[@@@ocaml.warning "-26-27"] 2 3open React 4 5type handle_status = Idle | Checking | Valid | Invalid of string 6 7let[@react.component] make ~name ?(label = "handle") ?(sr_only = false) 8 ?(required = false) ?(showIndicator = true) ?(subdomainOnly = false) 9 ?placeholder ?hostname ?value ?onChange () = 10 let internalValue, setInternalValue = useState (fun () -> "") in 11 let handleValue = Option.value value ~default:internalValue in 12 let handleStatus, setHandleStatus = useState (fun () -> Idle) in 13 let checkTimeoutRef = useRef None in 14 let checkHandle = 15 [%browser_only 16 fun handle -> 17 setHandleStatus (fun _ -> Checking) ; 18 let fullHandle = 19 match hostname with 20 | Some host -> 21 handle ^ "." ^ host 22 | None -> 23 handle 24 in 25 let _ = 26 Fetch.fetch 27 ( "/account/signup/check-handle?handle=" 28 ^ Js.Global.encodeURIComponent handle ) 29 |> Js.Promise.then_ (fun response -> 30 if Fetch.Response.ok response then Fetch.Response.json response 31 else Js.Promise.reject (Js.Exn.raiseError "Request failed") ) 32 |> Js.Promise.then_ (fun json -> 33 let valid = 34 Js.Dict.get (Obj.magic json) "valid" 35 |> Option.map Obj.magic 36 |> Option.value ~default:false 37 in 38 let available = 39 Js.Dict.get (Obj.magic json) "available" 40 |> Option.map Obj.magic 41 |> Option.value ~default:false 42 in 43 let error = 44 Option.bind 45 (Js.Dict.get (Obj.magic json) "error" |> Option.map Obj.magic) 46 (fun x -> 47 if Js.Nullable.isNullable (Obj.magic x) then None 48 else Some x ) 49 in 50 if valid && available then setHandleStatus (fun _ -> Valid) 51 else 52 setHandleStatus (fun _ -> 53 Invalid (Option.value error ~default:"Invalid handle") ) ; 54 Js.Promise.resolve () ) 55 |> Js.Promise.catch (fun _ -> 56 setHandleStatus (fun _ -> 57 Invalid "Couldn't check handle availability" ) ; 58 Js.Promise.resolve () ) 59 in 60 ()] 61 in 62 let onHandleChange = 63 [%browser_only 64 fun e -> 65 let inputValue = (Event.Form.target e)##value in 66 ( match onChange with 67 | Some f -> 68 f e 69 | None -> 70 setInternalValue (fun _ -> inputValue) ) ; 71 ( match checkTimeoutRef.current with 72 | Some id -> 73 Js.Global.clearTimeout id 74 | None -> 75 () ) ; 76 if String.length inputValue = 0 then setHandleStatus (fun _ -> Idle) 77 else 78 let id = 79 Js.Global.setTimeout ~f:(fun () -> checkHandle inputValue) 300 80 in 81 checkTimeoutRef.current <- Some id] 82 in 83 let trailing = 84 match hostname with 85 | Some h -> 86 Some 87 <span className="font-serif text-mist-80 whitespace-nowrap"> 88 (string ("." ^ h)) 89 </span> 90 | _ -> 91 None 92 in 93 <div> 94 <Input 95 sr_only 96 name 97 type_="text" 98 label 99 value=handleValue 100 onChange=onHandleChange 101 required 102 showIndicator 103 ?placeholder 104 ?trailing 105 /> 106 ( match handleStatus with 107 | Checking -> 108 <span className="text-mist-80 text-sm mt-1 block"> 109 (string "Checking availability...") 110 </span> 111 | Valid -> 112 <span className="inline-flex items-center text-mana-100 text-sm mt-1"> 113 <CheckmarkIcon className="w-4 h-4 mr-1" /> 114 (string "Handle is available") 115 </span> 116 | Invalid msg -> 117 <span 118 className="inline-flex items-center text-phoenix-100 text-sm mt-1"> 119 <CircleAlertIcon className="w-4 h-4 mr-1" /> (string msg) 120 </span> 121 | Idle -> 122 null ) 123 </div>