Get primary user flow working on desktop
This commit is contained in:
@ -8,3 +8,5 @@ VITE_KC_SKIP_AUTH=false
|
||||
VITE_KC_CONNECTION_TIMEOUT_MS=5000
|
||||
# ONLY add your token in .env.development.local if you want to skip auth, otherwise this token takes precedence!
|
||||
#VITE_KC_DEV_TOKEN="your token from dev.zoo.dev should go in .env.development.local"
|
||||
# Add a prod token if you want to use the share URL feature in local dev
|
||||
#VITE_KC_PROD_TOKEN="your token from prod.zoo.dev should go in .env.development.local"
|
1
interface.d.ts
vendored
1
interface.d.ts
vendored
@ -62,6 +62,7 @@ export interface IElectronAPI {
|
||||
TEST_SETTINGS_FILE_KEY: string
|
||||
IS_PLAYWRIGHT: string
|
||||
VITE_KC_DEV_TOKEN: string
|
||||
VITE_KC_PROD_TOKEN: string
|
||||
VITE_KC_API_WS_MODELING_URL: string
|
||||
VITE_KC_API_BASE_URL: string
|
||||
VITE_KC_SITE_BASE_URL: string
|
||||
|
@ -47,7 +47,6 @@ import { AppStateProvider } from 'AppState'
|
||||
import { reportRejection } from 'lib/trap'
|
||||
import { RouteProvider } from 'components/RouteProvider'
|
||||
import { ProjectsContextProvider } from 'components/ProjectsContextProvider'
|
||||
import { ProtocolHandler } from 'components/ProtocolHandler'
|
||||
|
||||
const createRouter = isDesktop() ? createHashRouter : createBrowserRouter
|
||||
|
||||
@ -59,7 +58,6 @@ const router = createRouter([
|
||||
/* Make sure auth is the outermost provider or else we will have
|
||||
* inefficient re-renders, use the react profiler to see. */
|
||||
element: (
|
||||
<ProtocolHandler>
|
||||
<CommandBarProvider>
|
||||
<RouteProvider>
|
||||
<SettingsAuthProvider>
|
||||
@ -77,7 +75,6 @@ const router = createRouter([
|
||||
</SettingsAuthProvider>
|
||||
</RouteProvider>
|
||||
</CommandBarProvider>
|
||||
</ProtocolHandler>
|
||||
),
|
||||
errorElement: <ErrorPage />,
|
||||
children: [
|
||||
|
@ -18,6 +18,8 @@ import Tooltip from './Tooltip'
|
||||
import { createFileLink } from 'lib/createFileLink'
|
||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||
import toast from 'react-hot-toast'
|
||||
import { DEV, VITE_KC_PROD_TOKEN } from 'env'
|
||||
import { err } from 'lib/trap'
|
||||
|
||||
const ProjectSidebarMenu = ({
|
||||
project,
|
||||
@ -189,21 +191,41 @@ function ProjectMenuPopover({
|
||||
Element: 'button',
|
||||
children: 'Share link to file',
|
||||
onClick: async () => {
|
||||
if (!auth.context.token) {
|
||||
/**
|
||||
* We don't have a dev shortlink API service,
|
||||
* so we need to hit the prod API even in local dev.
|
||||
* This override allows us to shim in an environment variable
|
||||
* for the prod token.
|
||||
*/
|
||||
const token = DEV ? VITE_KC_PROD_TOKEN : auth.context.token
|
||||
if (DEV && !VITE_KC_PROD_TOKEN) {
|
||||
toast.error(
|
||||
'You need to set a prod token in your environment to share a file in development.',
|
||||
{
|
||||
duration: 5000,
|
||||
}
|
||||
)
|
||||
return
|
||||
} else if (!token) {
|
||||
toast.error('You need to be signed in to share a file.', {
|
||||
duration: 5000,
|
||||
})
|
||||
return
|
||||
}
|
||||
const shareUrl = await createFileLink(auth.context.token, {
|
||||
const shareUrl = await createFileLink(token, {
|
||||
code: codeManager.code,
|
||||
name: file?.name || '',
|
||||
name: project?.name || '',
|
||||
units: settings.context.modeling.defaultUnit.current,
|
||||
})
|
||||
|
||||
console.log(shareUrl)
|
||||
if (err(shareUrl)) {
|
||||
toast.error(shareUrl.message, {
|
||||
duration: 5000,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
await globalThis.navigator.clipboard.writeText(shareUrl)
|
||||
await globalThis.navigator.clipboard.writeText(shareUrl.url)
|
||||
toast.success(
|
||||
'Link copied to clipboard. Anyone who clicks this link will get a copy of this file. Share carefully!',
|
||||
{
|
||||
|
@ -14,6 +14,7 @@ export const VITE_KC_SKIP_AUTH = env.VITE_KC_SKIP_AUTH as string | undefined
|
||||
export const VITE_KC_CONNECTION_TIMEOUT_MS =
|
||||
env.VITE_KC_CONNECTION_TIMEOUT_MS as string | undefined
|
||||
export const VITE_KC_DEV_TOKEN = env.VITE_KC_DEV_TOKEN as string | undefined
|
||||
export const VITE_KC_PROD_TOKEN = env.VITE_KC_PROD_TOKEN as string | undefined
|
||||
export const PROD = env.PROD as string | undefined
|
||||
export const TEST = env.TEST as string | undefined
|
||||
export const DEV = env.DEV as string | undefined
|
||||
|
@ -1,10 +1,7 @@
|
||||
import { UnitLength_type } from '@kittycad/lib/dist/types/src/models'
|
||||
import { postUserShortlink } from 'lib/desktop'
|
||||
import { CREATE_FILE_URL_PARAM } from './constants'
|
||||
import { stringToBase64 } from './base64'
|
||||
import withBaseURL from 'lib/withBaseURL'
|
||||
import { isDesktop } from 'lib/isDesktop'
|
||||
|
||||
import { ZOO_STUDIO_PROTOCOL } from './link'
|
||||
export interface FileLinkParams {
|
||||
code: string
|
||||
name: string
|
||||
@ -13,41 +10,44 @@ export interface FileLinkParams {
|
||||
|
||||
/**
|
||||
* Given a file's code, name, and units, creates shareable link
|
||||
* TODO: update the return type to use TS library after its updated
|
||||
*/
|
||||
export async function createFileLink(
|
||||
token: string,
|
||||
{ code, name, units }: FileLinkParams
|
||||
) {
|
||||
let urlUserShortlinks = withBaseURL('/users/shortlinks')
|
||||
|
||||
): Promise<Error | { key: string; url: string }> {
|
||||
// During development, the "handler" needs to first be the web app version,
|
||||
// which exists on localhost:3000 typically.
|
||||
let origin = 'http://localhost:3000'
|
||||
|
||||
let urlFileToShare = new URL(
|
||||
`/?${CREATE_FILE_URL_PARAM}&name=${encodeURIComponent(
|
||||
`?${CREATE_FILE_URL_PARAM}&name=${encodeURIComponent(
|
||||
name
|
||||
)}&units=${units}&code=${encodeURIComponent(stringToBase64(code))}`,
|
||||
origin
|
||||
).toString()
|
||||
|
||||
// Remove this monkey patching
|
||||
function fixTheBrokenShitUntilItsFixedOnDev() {
|
||||
urlUserShortlinks = urlUserShortlinks.replace(
|
||||
'https://api.dev.zoo.dev',
|
||||
'https://api.zoo.dev'
|
||||
)
|
||||
console.log(urlUserShortlinks)
|
||||
}
|
||||
|
||||
fixTheBrokenShitUntilItsFixedOnDev()
|
||||
|
||||
return await fetch(urlUserShortlinks, {
|
||||
/**
|
||||
* We don't use our `withBaseURL` function here because
|
||||
* there is no URL shortener service in the dev API.
|
||||
*/
|
||||
const response = await fetch('https://api.zoo.dev/user/shortlinks', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ url: urlFileToShare }),
|
||||
}).then((resp) => resp.json())
|
||||
body: JSON.stringify({
|
||||
url: urlFileToShare,
|
||||
// In future we can support org-scoped and password-protected shortlinks here
|
||||
// https://zoo.dev/docs/api/shortlinks/create-a-shortlink-for-a-user?lang=typescript
|
||||
}),
|
||||
})
|
||||
console.log('response', response)
|
||||
if (!response.ok) {
|
||||
const error = await response.json()
|
||||
return new Error(`Failed to create shortlink: ${error.message}`)
|
||||
} else {
|
||||
return response.json()
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
export const ZOO_STUDIO_PROTOCOL = 'zoo-studio'
|
||||
export const ZOO_STUDIO_PROTOCOL = 'zoo-studio:'
|
||||
|
32
src/main.ts
32
src/main.ts
@ -67,7 +67,7 @@ if (process.defaultApp) {
|
||||
// Must be done before ready event.
|
||||
registerStartupListeners()
|
||||
|
||||
const createWindow = (filePath?: string, reuse?: boolean): BrowserWindow => {
|
||||
const createWindow = (pathToOpen?: string, reuse?: boolean): BrowserWindow => {
|
||||
let newWindow
|
||||
|
||||
if (reuse) {
|
||||
@ -92,12 +92,27 @@ const createWindow = (filePath?: string, reuse?: boolean): BrowserWindow => {
|
||||
})
|
||||
}
|
||||
|
||||
const pathIsCustomProtocolLink = pathToOpen?.startsWith(ZOO_STUDIO_PROTOCOL) ?? false
|
||||
|
||||
// and load the index.html of the app.
|
||||
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
|
||||
newWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL).catch(reportRejection)
|
||||
const filteredPath = pathToOpen ? decodeURI(pathToOpen.replace(ZOO_STUDIO_PROTOCOL, '')) : ''
|
||||
const fullHashBasedUrl = `${MAIN_WINDOW_VITE_DEV_SERVER_URL}/#/${filteredPath}`
|
||||
newWindow.loadURL(fullHashBasedUrl).catch(reportRejection)
|
||||
} else {
|
||||
console.log('Loading from file', filePath)
|
||||
getProjectPathAtStartup(filePath)
|
||||
if (pathIsCustomProtocolLink && pathToOpen) {
|
||||
// We're trying to open a custom protocol link
|
||||
const filteredPath = pathToOpen ? decodeURI(pathToOpen.replace(ZOO_STUDIO_PROTOCOL, '')) : ''
|
||||
const startIndex = path.join(
|
||||
__dirname,
|
||||
`../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`
|
||||
)
|
||||
newWindow.loadFile(startIndex, {
|
||||
hash: filteredPath,
|
||||
}).catch(reportRejection)
|
||||
} else {
|
||||
// otherwise we're trying to open a local file from the command line
|
||||
getProjectPathAtStartup(pathToOpen)
|
||||
.then(async (projectPath) => {
|
||||
const startIndex = path.join(
|
||||
__dirname,
|
||||
@ -109,8 +124,6 @@ const createWindow = (filePath?: string, reuse?: boolean): BrowserWindow => {
|
||||
return
|
||||
}
|
||||
|
||||
console.log('Loading file', projectPath)
|
||||
|
||||
const fullUrl = `/file/${encodeURIComponent(projectPath)}`
|
||||
console.log('Full URL', fullUrl)
|
||||
|
||||
@ -120,6 +133,7 @@ const createWindow = (filePath?: string, reuse?: boolean): BrowserWindow => {
|
||||
})
|
||||
.catch(reportRejection)
|
||||
}
|
||||
}
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
@ -467,12 +481,6 @@ function registerStartupListeners() {
|
||||
) {
|
||||
event.preventDefault()
|
||||
|
||||
console.log('open-url', url)
|
||||
fs.writeFileSync(
|
||||
'/Users/frankjohnson/open-url.txt',
|
||||
`at ${new Date().toLocaleTimeString()} opened url: ${url}`
|
||||
)
|
||||
|
||||
// If we have a mainWindow, lets open another window.
|
||||
if (mainWindow) {
|
||||
createWindow(url)
|
||||
|
@ -188,6 +188,7 @@ contextBridge.exposeInMainWorld('electron', {
|
||||
'VITE_KC_SKIP_AUTH',
|
||||
'VITE_KC_CONNECTION_TIMEOUT_MS',
|
||||
'VITE_KC_DEV_TOKEN',
|
||||
'VITE_KC_PROD_TOKEN',
|
||||
'IS_PLAYWRIGHT',
|
||||
|
||||
// Really we shouldn't use these and our code should use NODE_ENV
|
||||
|
Reference in New Issue
Block a user