feat(tailshare): start implementing the new file sharing app #28

Merged
codinget merged 27 commits from feat/tailshare into main 2026-07-25 23:31:14 +02:00
Showing only changes of commit a9d588d7fa - Show all commits
+59 -4
View File
@@ -8,11 +8,21 @@ import {
useBuildIpn,
} from "@webnet/tsconnect-react"
import { buildIpnStore, getIpnState, type IpnStore } from "@webnet/tsconnect-redux"
import { type ReactNode, useEffect, useMemo, useRef, useState } from "react"
import { type ReactNode, useEffect, useEffectEvent, useMemo, useRef, useState } from "react"
import { initIPN, InMemoryFileOps, IPN, WebStorageState } from "@webnet/tsconnect"
import { useClient } from "../hooks/useClient"
import { useTailshareDispatch, useTailshareSelector } from "../store/store"
import { getIpnPrepareWillBuild, triggerIpnPrepareBuild } from "../store/slices/ipnPrepare"
import {
getIpnPrepareWillBuild,
selectIpnPrepareSlice,
setIpnPrepareAuthKey,
setIpnPrepareControlURL,
setIpnPrepareHostname,
setIpnPrepareTaildrop,
triggerIpnPrepareBuild,
type IpnPrepare,
type TaildropOptions,
} from "../store/slices/ipnPrepare"
import wasmUrl from "@webnet/tsconnect/main.wasm"
import { useLocalStorage } from "@mantine/hooks"
@@ -68,7 +78,12 @@ export function IpnProvider({ children }: { children: ReactNode }) {
<AutoLogin ipn={ipn} />
</>
)}
{client && (
<>
<AutoInit />
<AutoConfig />
</>
)}
<IpnContext value={ipn}>{children}</IpnContext>
</IpnStoreProvider>
)
@@ -94,10 +109,50 @@ function AutoInit() {
}, [state, setAutostart])
useEffect(() => {
if (autostart === "1") {
window.setTimeout(() => dispatch(triggerIpnPrepareBuild()), 1000)
if (autostart !== "1") return
const timeout = window.setTimeout(() => dispatch(triggerIpnPrepareBuild()), 1000)
return () => {
window.clearTimeout(timeout)
}
}, [dispatch, autostart])
return null
}
function AutoConfig() {
const ipnPrepare = useTailshareSelector(selectIpnPrepareSlice)
const dispatch = useTailshareDispatch()
const [taildrop, setTaildrop] = useLocalStorage<TaildropOptions>({ key: "ipn#taildrop" })
const [hostname, setHostname, clearHostname] = useLocalStorage({ key: "ipn#hostname" })
const [controlURL, setControlURL, clearControlURL] = useLocalStorage({ key: "ipn#controlURL" })
const [authKey, setAuthKey, clearAuthKey] = useLocalStorage({ key: "ipn#authKey" })
const [hasPrepared, setHasPrepared] = useState(false)
const updateLocalStorage = useEffectEvent((ipnPrepare: IpnPrepare) => {
setTaildrop(ipnPrepare.taildrop)
if (ipnPrepare.hostname) setHostname(ipnPrepare.hostname)
else clearHostname()
if (ipnPrepare.controlURL) setControlURL(ipnPrepare.controlURL)
else clearControlURL()
if (ipnPrepare.authKey) setAuthKey(ipnPrepare.authKey)
else clearAuthKey()
})
useEffect(() => {
if (!hasPrepared) return
updateLocalStorage(ipnPrepare)
}, [ipnPrepare, hasPrepared])
const setPrepare = useEffectEvent(() => {
if (taildrop === "memory" || taildrop === "disable") dispatch(setIpnPrepareTaildrop(taildrop))
if (hostname) dispatch(setIpnPrepareHostname(hostname))
if (controlURL) dispatch(setIpnPrepareControlURL(controlURL))
if (authKey) dispatch(setIpnPrepareAuthKey(authKey))
setHasPrepared(true)
})
useEffect(() => {
setPrepare()
}, [])
return null
}