feat(tailshare): start implementing the new file sharing app #28
@@ -24,7 +24,6 @@ import {
|
||||
setIpnPrepareAuthKey,
|
||||
setIpnPrepareControlURL,
|
||||
setIpnPrepareHostname,
|
||||
setIpnPrepareTaildrop,
|
||||
triggerIpnBuild,
|
||||
type IpnPrepare,
|
||||
} from "../store/slices/ipnPrepare"
|
||||
@@ -60,7 +59,7 @@ export function IpnProvider({ children }: { children: ReactNode }) {
|
||||
const builderParams: Parameters<IpnBuilder>[0] = {}
|
||||
if (!willBuild) return builderParams
|
||||
|
||||
if (willBuild.taildrop === "memory") builderParams.fileOps = new InMemoryFileOps()
|
||||
builderParams.fileOps = new InMemoryFileOps()
|
||||
|
||||
if (client && localStorage) {
|
||||
builderParams.stateStorage = new WebStorageState(localStorage, "ipn:")
|
||||
@@ -159,7 +158,6 @@ function AutoInit() {
|
||||
function AutoConfig() {
|
||||
const ipnPrepare = useTailshareSelector(selectIpnPrepareSlice)
|
||||
const dispatch = useTailshareDispatch()
|
||||
const [taildrop, setTaildrop] = useLocalStorage("ipn#taildrop")
|
||||
const [hostname, setHostname, clearHostname] = useLocalStorage("ipn#hostname")
|
||||
const [controlURL, setControlURL, clearControlURL] = useLocalStorage("ipn#controlURL")
|
||||
const [authKey, setAuthKey, clearAuthKey] = useLocalStorage("ipn#authKey")
|
||||
@@ -167,7 +165,6 @@ function AutoConfig() {
|
||||
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)
|
||||
@@ -181,7 +178,6 @@ function AutoConfig() {
|
||||
}, [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))
|
||||
|
||||
@@ -20,8 +20,3 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.willRestart {
|
||||
position: relative;
|
||||
top: -0.25em;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import {
|
||||
setIpnPrepareAuthKey,
|
||||
setIpnPrepareControlURL,
|
||||
setIpnPrepareHostname,
|
||||
setIpnPrepareTaildrop,
|
||||
triggerIpnBuild,
|
||||
} from "../store/slices/ipnPrepare"
|
||||
import {
|
||||
@@ -46,7 +45,7 @@ import { CopyIcon, DownloadIcon, TrashIcon } from "@phosphor-icons/react"
|
||||
import { useDisclosure } from "@mantine/hooks"
|
||||
import clsx from "clsx"
|
||||
import { useLocalStorage } from "../hooks/useLocalStorage"
|
||||
import type { IPN, IPNWaitingFile } from "@webnet/tsconnect"
|
||||
import type { IpnClient, IPNWaitingFile } from "@webnet/tsconnect"
|
||||
import { fmtSize } from "../utils/format"
|
||||
import { download } from "../utils/download"
|
||||
import { setTailnetDrawerOpen } from "../store/slices/states"
|
||||
@@ -114,8 +113,7 @@ function TailscaleConfig() {
|
||||
|
||||
const requireRestart =
|
||||
ipnPrepare.willBuild &&
|
||||
(ipnPrepare.taildrop !== ipnPrepare.willBuild.taildrop ||
|
||||
ipnPrepare.authKey !== ipnPrepare.willBuild.authKey ||
|
||||
(ipnPrepare.authKey !== ipnPrepare.willBuild.authKey ||
|
||||
ipnPrepare.controlURL !== ipnPrepare.willBuild.controlURL ||
|
||||
ipnPrepare.hostname !== ipnPrepare.willBuild.hostname)
|
||||
|
||||
@@ -141,26 +139,20 @@ function TailscaleConfig() {
|
||||
)}
|
||||
<TextInput
|
||||
mt="xs"
|
||||
label={
|
||||
<>
|
||||
Hostname
|
||||
<Text unstyled className={styles.willRestart} component="span" c="red">
|
||||
*
|
||||
</Text>
|
||||
</>
|
||||
}
|
||||
withAsterisk
|
||||
label={<>Hostname</>}
|
||||
placeholder="(Autogen on startup)"
|
||||
value={ipnPrepare.hostname ?? ""}
|
||||
onChange={(e) => dispatch(setIpnPrepareHostname(e.target.value))}
|
||||
/>
|
||||
<TextInput
|
||||
mt="xs"
|
||||
label={
|
||||
withAsterisk
|
||||
label={<>Pregenerated authkey</>}
|
||||
description={
|
||||
<>
|
||||
Pregenerated authkey
|
||||
<Text unstyled className={styles.willRestart} component="span" c="red">
|
||||
*
|
||||
</Text>
|
||||
This is a soft credential that will be stored in the browser - only set this if you
|
||||
must, logging in manually is more secure
|
||||
</>
|
||||
}
|
||||
placeholder="(Manual login flow)"
|
||||
@@ -169,14 +161,8 @@ function TailscaleConfig() {
|
||||
/>
|
||||
<TextInput
|
||||
mt="xs"
|
||||
label={
|
||||
<>
|
||||
Control plane URL
|
||||
<Text unstyled className={styles.willRestart} component="span" c="red">
|
||||
*
|
||||
</Text>
|
||||
</>
|
||||
}
|
||||
withAsterisk
|
||||
label={<>Control plane URL</>}
|
||||
placeholder="(Default Tailscale control plane)"
|
||||
value={ipnPrepare.controlURL ?? ""}
|
||||
onChange={(e) => dispatch(setIpnPrepareControlURL(e.target.value))}
|
||||
@@ -187,19 +173,6 @@ function TailscaleConfig() {
|
||||
checked={autostart === "1"}
|
||||
onChange={(e) => setAutostart("" + +e.target.checked)}
|
||||
/>
|
||||
<Checkbox
|
||||
mt="xs"
|
||||
label={
|
||||
<>
|
||||
Enable Taildrop
|
||||
<Text unstyled className={styles.willRestart} component="span" c="red">
|
||||
*
|
||||
</Text>
|
||||
</>
|
||||
}
|
||||
checked={ipnPrepare.taildrop === "memory"}
|
||||
onChange={(e) => dispatch(setIpnPrepareTaildrop(e.target.checked ? "memory" : "disable"))}
|
||||
/>
|
||||
<Box className={clsx(styles.restartLine, requireRestart || styles.hidden)}>
|
||||
<Text mt="xs" c="dimmed">
|
||||
Restart required to apply the changes.
|
||||
@@ -304,7 +277,7 @@ function TailscaleWaitingFiles({
|
||||
ipn,
|
||||
}: {
|
||||
waitingFiles: Record<string, IPNWaitingFile>
|
||||
ipn: IPN
|
||||
ipn: IpnClient
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { createSlice, type PayloadAction, type Store } from "@reduxjs/toolkit"
|
||||
|
||||
export type TaildropOptions = "disable" | "memory"
|
||||
|
||||
export type IpnPrepare = {
|
||||
taildrop: TaildropOptions
|
||||
|
||||
hostname: string | null
|
||||
controlURL: string | null
|
||||
authKey: string | null
|
||||
@@ -13,7 +9,6 @@ export type IpnPrepare = {
|
||||
alreadyRunning: boolean
|
||||
}
|
||||
const initialState: IpnPrepare = {
|
||||
taildrop: "memory",
|
||||
hostname: null,
|
||||
controlURL: null,
|
||||
authKey: null,
|
||||
@@ -25,9 +20,6 @@ export const ipnPrepareSlice = createSlice({
|
||||
name: "ipnPrepare",
|
||||
initialState,
|
||||
reducers: {
|
||||
setIpnPrepareTaildrop: (state, action: PayloadAction<TaildropOptions>) => {
|
||||
state.taildrop = action.payload
|
||||
},
|
||||
setIpnPrepareHostname: (state, action: PayloadAction<string | null>) => {
|
||||
state.hostname = action.payload || null
|
||||
},
|
||||
@@ -45,7 +37,6 @@ export const ipnPrepareSlice = createSlice({
|
||||
},
|
||||
},
|
||||
selectors: {
|
||||
getIpnPrepareTaildrop: (state) => state.taildrop,
|
||||
getIpnPrepareHostname: (state) => state.hostname,
|
||||
getIpnPrepareControlURL: (state) => state.controlURL,
|
||||
getIpnPrepareAuthKey: (state) => state.authKey,
|
||||
@@ -55,17 +46,11 @@ export const ipnPrepareSlice = createSlice({
|
||||
})
|
||||
|
||||
export const {
|
||||
actions: {
|
||||
setIpnPrepareAuthKey,
|
||||
setIpnPrepareControlURL,
|
||||
setIpnPrepareHostname,
|
||||
setIpnPrepareTaildrop,
|
||||
},
|
||||
actions: { setIpnPrepareAuthKey, setIpnPrepareControlURL, setIpnPrepareHostname },
|
||||
selectors: {
|
||||
getIpnPrepareControlURL,
|
||||
getIpnPrepareAuthKey,
|
||||
getIpnPrepareHostname,
|
||||
getIpnPrepareTaildrop,
|
||||
getIpnPrepareWillBuild,
|
||||
getIpnPrepareAlreadyRunning,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user