Fix docs link, test fixing relative URLs in Windows (#606)

* Fix #593: don't prevent default on link click

* Use absolute/explicit path for settings
Trying to test fix for #594

* Broken: replace almost all relative URLs with absolute

* add relative jump backs util

* dot dot slash everywhere

* use usLocation not window.location

* the one that got away

* fmt 🤦‍♂️

---------

Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
This commit is contained in:
Frank Noirot
2023-09-18 23:55:14 -04:00
committed by GitHub
parent 8147f5f1eb
commit 488e41ac0e
19 changed files with 117 additions and 65 deletions

View File

@ -23,7 +23,8 @@ export const CodeMenu = ({ children }: PropsWithChildren) => {
<div
className="relative"
onClick={(e) => {
if (e.eventPhase === 3) {
const target = e.target as HTMLElement
if (e.eventPhase === 3 && target.closest('a') === null) {
e.stopPropagation()
e.preventDefault()
}

View File

@ -16,7 +16,7 @@ const ProjectSidebarMenu = ({
}) => {
return renderAsLink ? (
<Link
to={'../'}
to={paths.HOME}
className="h-9 max-h-min min-w-max border-0 p-0.5 pr-2 flex items-center gap-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50"
data-testid="project-sidebar-link"
>

View File

@ -2,7 +2,7 @@ import { Popover, Transition } from '@headlessui/react'
import { ActionButton } from './ActionButton'
import { faBars, faGear, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
import { useNavigate } from 'react-router-dom'
import { useLocation, useNavigate } from 'react-router-dom'
import { Fragment, useState } from 'react'
import { paths } from '../Router'
import makeUrlPathRelative from '../lib/makeUrlPathRelative'
@ -12,6 +12,7 @@ import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
type User = Models['User_type']
const UserSidebarMenu = ({ user }: { user?: User }) => {
const location = useLocation()
const displayedName = getDisplayName(user)
const [imageLoadFailed, setImageLoadFailed] = useState(false)
const navigate = useNavigate()
@ -126,7 +127,11 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
// since /settings is a nested route the sidebar doesn't close
// automatically when navigating to it
close()
navigate(makeUrlPathRelative(paths.SETTINGS))
navigate(
(location.pathname.endsWith('/')
? location.pathname.slice(0, -1)
: location.pathname) + paths.SETTINGS
)
}}
>
Settings

View File

@ -0,0 +1,13 @@
import { useLocation } from 'react-router-dom'
export function useDotDotSlash(): (count?: number) => string {
const location = useLocation()
const dotDotSlash = (count = 1): string => {
// since we can't use relative paths (../) for windows
if (location.pathname === '/') return ''
const path = location.pathname.slice(0, location.pathname.lastIndexOf('/'))
if (count <= 1) return path
return dotDotSlash(count - 1)
}
return dotDotSlash
}

View File

@ -9,6 +9,7 @@ import {
cameraMouseDragGuards,
cameraSystems,
} from 'lib/cameraControls'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function Units() {
const { buttonDownInStream } = useStore((s) => ({
@ -24,6 +25,7 @@ export default function Units() {
},
},
} = useGlobalStateContext()
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
@ -72,7 +74,7 @@ export default function Units() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -2,6 +2,7 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons'
import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function CmdK() {
const { buttonDownInStream } = useStore((s) => ({
@ -9,6 +10,7 @@ export default function CmdK() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.USER_MENU)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
@ -41,7 +43,7 @@ export default function CmdK() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -3,6 +3,7 @@ import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { useBackdropHighlight } from 'hooks/useBackdropHighlight'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function CodeEditor() {
const { buttonDownInStream } = useStore((s) => ({
@ -10,6 +11,7 @@ export default function CodeEditor() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.PARAMETRIC_MODELING)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
@ -60,7 +62,7 @@ export default function CodeEditor() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -2,6 +2,7 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons'
import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function Export() {
const { buttonDownInStream } = useStore((s) => ({
@ -9,6 +10,7 @@ export default function Export() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.SKETCHING)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
@ -40,7 +42,7 @@ export default function Export() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -4,12 +4,14 @@ import { useDismiss } from '.'
import { useEffect } from 'react'
import { useStore } from 'useStore'
import { bracket } from 'lib/exampleKcl'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function FutureWork() {
const dismiss = useDismiss()
const { deferredSetCode } = useStore((s) => ({
deferredSetCode: s.deferredSetCode,
}))
const dotDotSlash = useDotDotSlash()
useEffect(() => {
deferredSetCode(bracket)
@ -34,7 +36,7 @@ export default function FutureWork() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -47,7 +49,7 @@ export default function FutureWork() {
</ActionButton>
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{ icon: faArrowRight }}
>
Finish

View File

@ -3,6 +3,7 @@ import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { useBackdropHighlight } from 'hooks/useBackdropHighlight'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function InteractiveNumbers() {
const { buttonDownInStream } = useStore((s) => ({
@ -10,6 +11,7 @@ export default function InteractiveNumbers() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.COMMAND_K)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
@ -33,6 +35,7 @@ export default function InteractiveNumbers() {
the <kbd>Alt</kbd> (or <kbd>Option</kbd>) key and dragging the
number left and right. You can hold down different modifier keys to
change the value by different increments:
</p>
<table className="border-collapse text-sm mx-auto my-4">
<tbody>
<tr>
@ -69,7 +72,6 @@ export default function InteractiveNumbers() {
</tr>
</tbody>
</table>
</p>
<p className="my-4">
Our code editor is built with{' '}
<a
@ -100,7 +102,7 @@ export default function InteractiveNumbers() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -15,13 +15,14 @@ import { isTauri } from 'lib/isTauri'
import { useNavigate } from 'react-router-dom'
import { paths } from 'Router'
import { useEffect } from 'react'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
function OnboardingWithNewFile() {
const navigate = useNavigate()
const dotDotSlash = useDotDotSlash()
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.INDEX)
const { setCode, code } = useStore((s) => ({
code: s.code,
const { setCode } = useStore((s) => ({
setCode: s.setCode,
}))
const {
@ -52,7 +53,7 @@ function OnboardingWithNewFile() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={() => dismiss('../')}
onClick={() => dismiss(dotDotSlash())}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -90,7 +91,7 @@ function OnboardingWithNewFile() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={() => dismiss('../')}
onClick={() => dismiss(dotDotSlash())}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -135,6 +136,7 @@ export default function Introduction() {
: ''
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.CAMERA)
const dotDotSlash = useDotDotSlash()
useEffect(() => {
if (code === '') setCode(bracket)
@ -178,7 +180,7 @@ export default function Introduction() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={() => dismiss('../')}
onClick={() => dismiss(dotDotSlash())}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -5,6 +5,7 @@ import { useStore } from '../../useStore'
import { useBackdropHighlight } from 'hooks/useBackdropHighlight'
import { Themes, getSystemTheme } from 'lib/theme'
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function ParametricModeling() {
const { buttonDownInStream } = useStore((s) => ({
@ -22,6 +23,7 @@ export default function ParametricModeling() {
: ''
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.INTERACTIVE_NUMBERS)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-end items-center inset-0 z-50 pointer-events-none">
@ -60,7 +62,7 @@ export default function ParametricModeling() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -3,6 +3,7 @@ import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { isTauri } from 'lib/isTauri'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function ProjectMenu() {
const { buttonDownInStream } = useStore((s) => ({
@ -10,6 +11,7 @@ export default function ProjectMenu() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.EXPORT)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
@ -31,7 +33,7 @@ export default function ProjectMenu() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -3,6 +3,7 @@ import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from 'useStore'
import { useEffect } from 'react'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function Sketching() {
const { deferredSetCode, buttonDownInStream } = useStore((s) => ({
@ -15,6 +16,7 @@ export default function Sketching() {
useEffect(() => {
deferredSetCode('')
}, [deferredSetCode])
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-center items-end inset-0 z-50 pointer-events-none">
@ -38,7 +40,7 @@ export default function Sketching() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -2,6 +2,7 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons'
import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function Streaming() {
const { buttonDownInStream } = useStore((s) => ({
@ -9,6 +10,7 @@ export default function Streaming() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.EDITOR)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-start items-center inset-0 z-50 pointer-events-none">
@ -41,7 +43,7 @@ export default function Streaming() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -6,6 +6,7 @@ import { Toggle } from '../../components/Toggle/Toggle'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
import { UnitSystem } from 'machines/settingsMachine'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function Units() {
const dismiss = useDismiss()
@ -16,6 +17,7 @@ export default function Units() {
context: { unitSystem, baseUnit },
},
} = useGlobalStateContext()
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid place-content-center inset-0 bg-chalkboard-110/50 z-50">
@ -66,7 +68,7 @@ export default function Units() {
<div className="flex justify-between mt-6">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -2,6 +2,7 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons'
import { ActionButton } from '../../components/ActionButton'
import { onboardingPaths, useDismiss, useNextClick } from '.'
import { useStore } from '../../useStore'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export default function UserMenu() {
const { buttonDownInStream } = useStore((s) => ({
@ -9,6 +10,7 @@ export default function UserMenu() {
}))
const dismiss = useDismiss()
const next = useNextClick(onboardingPaths.PROJECT_MENU)
const dotDotSlash = useDotDotSlash()
return (
<div className="fixed grid justify-center items-start inset-0 z-50 pointer-events-none">
@ -28,7 +30,7 @@ export default function UserMenu() {
<div className="flex justify-between">
<ActionButton
Element="button"
onClick={() => dismiss('../../')}
onClick={() => dismiss(dotDotSlash(2))}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',

View File

@ -1,5 +1,5 @@
import { useHotkeys } from 'react-hotkeys-hook'
import { Outlet, useNavigate } from 'react-router-dom'
import { Outlet, useLocation, useNavigate } from 'react-router-dom'
import Introduction from './Introduction'
import Camera from './Camera'
import Sketching from './Sketching'
@ -89,14 +89,16 @@ export function useNextClick(newStatus: string) {
settings: { send },
} = useGlobalStateContext()
const navigate = useNavigate()
const location = useLocation()
const lastSlashIndex = location.pathname.lastIndexOf('/')
return useCallback(() => {
send({
type: 'Set Onboarding Status',
data: { onboardingStatus: newStatus },
})
navigate((newStatus !== onboardingPaths.CAMERA ? '..' : '.') + newStatus)
}, [newStatus, send, navigate])
navigate(location.pathname.slice(0, lastSlashIndex) + newStatus)
}, [location, lastSlashIndex, newStatus, send, navigate])
}
export function useDismiss() {
@ -111,6 +113,7 @@ export function useDismiss() {
type: 'Set Onboarding Status',
data: { onboardingStatus: 'dismissed' },
})
console.log('yoyo', window.location.pathname, path)
navigate(path)
},
[send, navigate]
@ -118,8 +121,10 @@ export function useDismiss() {
}
const Onboarding = () => {
const location = useLocation()
const dismiss = useDismiss()
useHotkeys('esc', () => dismiss('../'))
const lastSlashIndex = location.pathname.lastIndexOf('/')
useHotkeys('esc', () => dismiss(location.pathname.slice(0, lastSlashIndex)))
return (
<>

View File

@ -23,12 +23,14 @@ import {
cameraMouseDragGuards,
} from 'lib/cameraControls'
import { UnitSystem } from 'machines/settingsMachine'
import { useDotDotSlash } from 'hooks/useDotDotSlash'
export const Settings = () => {
const loaderData = useRouteLoaderData(paths.FILE) as IndexLoaderData
const navigate = useNavigate()
const location = useLocation()
useHotkeys('esc', () => navigate('../'))
const dotDotSlash = useDotDotSlash()
useHotkeys('esc', () => navigate(dotDotSlash()))
const {
settings: {
send,
@ -66,7 +68,7 @@ export const Settings = () => {
<AppHeader showToolbar={false} project={loaderData?.project}>
<ActionButton
Element="link"
to={'../'}
to={location.pathname.replace(paths.SETTINGS, '')}
icon={{
icon: faXmark,
bgClassName: 'bg-destroy-80',
@ -267,7 +269,7 @@ export const Settings = () => {
type: 'Set Onboarding Status',
data: { onboardingStatus: '' },
})
navigate('..' + paths.ONBOARDING.INDEX)
navigate(dotDotSlash(1) + paths.ONBOARDING.INDEX)
}}
icon={{ icon: faArrowRotateBack }}
>