feat(site): Add support for insiders channel to "VS Code Desktop" button (#7730)

This commit is contained in:
Muhammad Atif Ali
2023-05-31 19:28:27 +03:00
committed by GitHub
parent 784696dfa5
commit b80756e4f5
5 changed files with 296 additions and 62 deletions

View File

@ -4,7 +4,7 @@ export const VSCodeIcon = (props: SvgIconProps) => (
<SvgIcon {...props} viewBox="0 0 100 100">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none">
<mask
id="mask0"
id="vscode_mask0"
mask-type="alpha"
maskUnits="userSpaceOnUse"
x="0"
@ -19,18 +19,18 @@ export const VSCodeIcon = (props: SvgIconProps) => (
fill="white"
/>
</mask>
<g mask="url(#mask0)">
<g mask="url(#vscode_mask0)">
<path
d="M96.4614 10.7962L75.8569 0.875542C73.4719 -0.272773 70.6217 0.211611 68.75 2.08333L1.29858 63.5832C-0.515693 65.2373 -0.513607 68.0937 1.30308 69.7452L6.81272 74.754C8.29793 76.1042 10.5347 76.2036 12.1338 74.9905L93.3609 13.3699C96.086 11.3026 100 13.2462 100 16.6667V16.4275C100 14.0265 98.6246 11.8378 96.4614 10.7962Z"
fill="#0065A9"
/>
<g filter="url(#filter0_d)">
<g filter="url(#vscode_filter0_d)">
<path
d="M96.4614 89.2038L75.8569 99.1245C73.4719 100.273 70.6217 99.7884 68.75 97.9167L1.29858 36.4169C-0.515693 34.7627 -0.513607 31.9063 1.30308 30.2548L6.81272 25.246C8.29793 23.8958 10.5347 23.7964 12.1338 25.0095L93.3609 86.6301C96.086 88.6974 100 86.7538 100 83.3334V83.5726C100 85.9735 98.6246 88.1622 96.4614 89.2038Z"
fill="#007ACC"
/>
</g>
<g filter="url(#filter1_d)">
<g filter="url(#vscode_filter1_d)">
<path
d="M75.8578 99.1263C73.4721 100.274 70.6219 99.7885 68.75 97.9166C71.0564 100.223 75 98.5895 75 95.3278V4.67213C75 1.41039 71.0564 -0.223106 68.75 2.08329C70.6219 0.211402 73.4721 -0.273666 75.8578 0.873633L96.4587 10.7807C98.6234 11.8217 100 14.0112 100 16.4132V83.5871C100 85.9891 98.6234 88.1786 96.4586 89.2196L75.8578 99.1263Z"
fill="#1F9CF0"
@ -46,13 +46,13 @@ export const VSCodeIcon = (props: SvgIconProps) => (
fillRule="evenodd"
clipRule="evenodd"
d="M70.8511 99.3171C72.4261 99.9306 74.2221 99.8913 75.8117 99.1264L96.4 89.2197C98.5634 88.1787 99.9392 85.9892 99.9392 83.5871V16.4133C99.9392 14.0112 98.5635 11.8217 96.4001 10.7807L75.8117 0.873695C73.7255 -0.13019 71.2838 0.115699 69.4527 1.44688C69.1912 1.63705 68.942 1.84937 68.7082 2.08335L29.2943 38.0414L12.1264 25.0096C10.5283 23.7964 8.29285 23.8959 6.80855 25.246L1.30225 30.2548C-0.513334 31.9064 -0.515415 34.7627 1.29775 36.4169L16.1863 50L1.29775 63.5832C-0.515415 65.2374 -0.513334 68.0937 1.30225 69.7452L6.80855 74.754C8.29285 76.1042 10.5283 76.2036 12.1264 74.9905L29.2943 61.9586L68.7082 97.9167C69.3317 98.5405 70.0638 99.0104 70.8511 99.3171ZM74.9544 27.2989L45.0483 50L74.9544 72.7012V27.2989Z"
fill="url(#paint0_linear)"
fill="url(#vscode_paint0_linear)"
/>
</g>
</g>
<defs>
<filter
id="filter0_d"
id="vscode_filter0_d"
x="-8.39411"
y="15.8291"
width="116.727"
@ -85,7 +85,7 @@ export const VSCodeIcon = (props: SvgIconProps) => (
/>
</filter>
<filter
id="filter1_d"
id="vscode_filter1_d"
x="60.4167"
y="-8.07558"
width="47.9167"
@ -118,7 +118,7 @@ export const VSCodeIcon = (props: SvgIconProps) => (
/>
</filter>
<linearGradient
id="paint0_linear"
id="vscode_paint0_linear"
x1="49.9392"
y1="0.257812"
x2="49.9392"

View File

@ -0,0 +1,126 @@
import SvgIcon, { SvgIconProps } from "@mui/material/SvgIcon"
export const VSCodeInsidersIcon = (props: SvgIconProps) => (
<SvgIcon {...props} viewBox="0 0 256 256">
<svg
width="256"
height="256"
viewBox="0 0 256 256"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<mask
id="mask0"
mask-type="alpha"
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="256"
height="256"
>
<path
d="M176.049 250.669C180.838 255.459 188.13 256.7 194.234 253.764L246.94 228.419C252.478 225.755 256 220.154 256 214.008V42.1479C256 36.0025 252.478 30.4008 246.94 27.7374L194.234 2.39089C188.13 -0.544416 180.838 0.696607 176.049 5.48572C181.95 -0.41506 192.039 3.76413 192.039 12.1091V244.046C192.039 252.391 181.95 256.57 176.049 250.669Z"
fill="white"
/>
<path
d="M181.379 180.646L114.33 128.633L181.379 75.5114V17.794C181.379 10.8477 173.128 7.20673 167.996 11.8862L74.6514 97.8518L31.1994 64.1438C27.1081 61.039 21.3851 61.294 17.5853 64.7476L3.48974 77.5627C-1.15847 81.7893 -1.16367 89.0948 3.47672 93.3292L167.98 244.185C173.107 248.887 181.379 245.249 181.379 238.292V180.646Z"
fill="white"
/>
<path
d="M36.6937 134.195L3.47672 162.828C-1.16367 167.062 -1.15847 174.37 3.48974 178.594L17.5853 191.409C21.3851 194.863 27.1081 195.118 31.1994 192.013L69.4472 164.057L36.6937 134.195Z"
fill="white"
/>
</mask>
<g mask="url(#mask0)">
<path
d="M167.996 11.8857C173.128 7.20627 181.379 10.8473 181.379 17.7936V75.5109L104.938 136.073L65.5742 106.211L167.996 11.8857Z"
fill="#009A7C"
/>
<path
d="M36.6937 134.194L3.47672 162.827C-1.16367 167.062 -1.15847 174.37 3.48974 178.594L17.5853 191.409C21.3851 194.863 27.1081 195.118 31.1994 192.013L69.4472 164.056L36.6937 134.194Z"
fill="#009A7C"
/>
<g filter="url(#filter0_d)">
<path
d="M181.379 180.645L31.1994 64.1427C27.1081 61.0379 21.3851 61.2929 17.5853 64.7465L3.48974 77.5616C-1.15847 81.7882 -1.16367 89.0937 3.47672 93.3281L167.972 244.176C173.102 248.881 181.379 245.241 181.379 238.28V180.645Z"
fill="#00B294"
/>
</g>
<g filter="url(#filter1_d)">
<path
d="M194.233 253.766C188.13 256.701 180.837 255.46 176.048 250.671C181.949 256.571 192.039 252.392 192.039 244.047V12.1103C192.039 3.76535 181.949 -0.413839 176.048 5.48694C180.837 0.697824 188.129 -0.543191 194.233 2.3921L246.939 27.7386C252.478 30.402 256 36.0037 256 42.1491V214.009C256 220.155 252.478 225.757 246.939 228.42L194.233 253.766Z"
fill="#24BFA5"
/>
</g>
</g>
<defs>
<filter
id="filter0_d"
x="-21.3333"
y="40.6413"
width="224.045"
height="226.988"
filterUnits="userSpaceOnUse"
colorInterpolationFilters="sRGB"
>
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
/>
<feOffset />
<feGaussianBlur stdDeviation="10.6667" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"
/>
<feBlend
mode="normal"
in2="BackgroundImageFix"
result="effect1_dropShadow"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow"
result="shape"
/>
</filter>
<filter
id="filter1_d"
x="154.715"
y="-20.5169"
width="122.618"
height="297.191"
filterUnits="userSpaceOnUse"
colorInterpolationFilters="sRGB"
>
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
/>
<feOffset />
<feGaussianBlur stdDeviation="10.6667" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
/>
<feBlend
mode="overlay"
in2="BackgroundImageFix"
result="effect1_dropShadow"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow"
result="shape"
/>
</filter>
</defs>
</svg>
</SvgIcon>
)

View File

@ -1,18 +1,27 @@
import { makeStyles } from "@mui/styles"
import Button, { ButtonProps } from "@mui/material/Button"
import { FC, forwardRef } from "react"
import { combineClasses } from "utils/combineClasses"
export const PrimaryAgentButton: FC<ButtonProps> = ({
className,
...props
}) => {
const styles = useStyles()
return (
<Button
className={combineClasses([styles.primaryButton, className])}
color="neutral"
{...props}
sx={{
backgroundColor: (theme) => theme.palette.background.default,
"&:hover": {
backgroundColor: (theme) => theme.palette.background.paper,
},
// Making them smaller since those icons don't have a padding around them
"& .MuiButton-startIcon": {
width: 12,
height: 12,
"& svg": { width: "100%", height: "100%" },
},
...props.sx,
}}
/>
)
}
@ -20,49 +29,6 @@ export const PrimaryAgentButton: FC<ButtonProps> = ({
// eslint-disable-next-line react/display-name -- Name is inferred from variable name
export const SecondaryAgentButton = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, ...props }, ref) => {
const styles = useStyles()
return (
<Button
ref={ref}
className={combineClasses([styles.secondaryButton, className])}
{...props}
/>
)
return <Button ref={ref} className={className} {...props} />
},
)
const useStyles = makeStyles((theme) => ({
primaryButton: {
whiteSpace: "nowrap",
backgroundColor: theme.palette.background.default,
height: 36,
minHeight: 36,
borderRadius: 4,
fontWeight: 500,
fontSize: 14,
"&:hover": {
backgroundColor: `${theme.palette.background.paper} !important`,
},
"& .MuiButton-startIcon": {
width: 12,
height: 12,
marginRight: theme.spacing(1.5),
"& svg": {
width: "100%",
height: "100%",
},
},
},
secondaryButton: {
fontSize: 14,
fontWeight: 500,
height: 36,
minHeight: 36,
borderRadius: 4,
},
}))

View File

@ -45,9 +45,7 @@ export const TerminalLink: FC<React.PropsWithChildren<TerminalLinkProps>> = ({
)
}}
>
<SecondaryAgentButton size="small">
{Language.linkText}
</SecondaryAgentButton>
<SecondaryAgentButton>{Language.linkText}</SecondaryAgentButton>
</Link>
)
}

View File

@ -1,7 +1,13 @@
import { FC, PropsWithChildren, useState, useRef } from "react"
import { getApiKey } from "api/api"
import { VSCodeIcon } from "components/Icons/VSCodeIcon"
import { FC, PropsWithChildren, useState } from "react"
import { VSCodeInsidersIcon } from "components/Icons/VSCodeInsidersIcon"
import { PrimaryAgentButton } from "components/Resources/AgentButton"
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"
import ButtonGroup from "@mui/material/ButtonGroup"
import { useLocalStorage } from "hooks"
import Menu from "@mui/material/Menu"
import MenuItem from "@mui/material/MenuItem"
export interface VSCodeDesktopButtonProps {
userName: string
@ -10,9 +16,103 @@ export interface VSCodeDesktopButtonProps {
folderPath?: string
}
type VSCodeVariant = "vscode" | "vscode-insiders"
const VARIANT_KEY = "vscode-variant"
export const VSCodeDesktopButton: FC<
PropsWithChildren<VSCodeDesktopButtonProps>
> = ({ userName, workspaceName, agentName, folderPath }) => {
> = (props) => {
const [isVariantMenuOpen, setIsVariantMenuOpen] = useState(false)
const localStorage = useLocalStorage()
const previousVariant = localStorage.getLocal(VARIANT_KEY)
const [variant, setVariant] = useState<VSCodeVariant>(() => {
if (!previousVariant) {
return "vscode"
}
return previousVariant as VSCodeVariant
})
const menuAnchorRef = useRef<HTMLDivElement>(null)
const selectVariant = (variant: VSCodeVariant) => {
localStorage.saveLocal(VARIANT_KEY, variant)
setVariant(variant)
setIsVariantMenuOpen(false)
}
return (
<div>
<ButtonGroup
ref={menuAnchorRef}
variant="outlined"
sx={{
// Workaround to make the border transitions smmothly on button groups
"& > button:hover + button": {
borderLeft: "1px solid #FFF",
},
}}
>
{variant === "vscode" ? (
<VSCodeButton {...props} />
) : (
<VSCodeInsidersButton {...props} />
)}
<PrimaryAgentButton
aria-controls={
isVariantMenuOpen ? "vscode-variant-button-menu" : undefined
}
aria-expanded={isVariantMenuOpen ? "true" : undefined}
aria-label="select VSCode variant"
aria-haspopup="menu"
disableRipple
onClick={() => {
setIsVariantMenuOpen(true)
}}
>
<KeyboardArrowDownIcon sx={{ fontSize: 16 }} />
</PrimaryAgentButton>
</ButtonGroup>
<Menu
open={isVariantMenuOpen}
anchorEl={menuAnchorRef.current}
onClose={() => setIsVariantMenuOpen(false)}
sx={{
"& .MuiMenu-paper": {
width: menuAnchorRef.current?.clientWidth,
},
}}
>
<MenuItem
sx={{ fontSize: 14 }}
onClick={() => {
selectVariant("vscode")
}}
>
<VSCodeIcon sx={{ width: 12, height: 12 }} />
VS Code Desktop
</MenuItem>
<MenuItem
sx={{ fontSize: 14 }}
onClick={() => {
selectVariant("vscode-insiders")
}}
>
<VSCodeInsidersIcon sx={{ width: 12, height: 12 }} />
VS Code Insiders
</MenuItem>
</Menu>
</div>
)
}
const VSCodeButton = ({
userName,
workspaceName,
agentName,
folderPath,
}: VSCodeDesktopButtonProps) => {
const [loading, setLoading] = useState(false)
return (
@ -50,3 +150,47 @@ export const VSCodeDesktopButton: FC<
</PrimaryAgentButton>
)
}
const VSCodeInsidersButton = ({
userName,
workspaceName,
agentName,
folderPath,
}: VSCodeDesktopButtonProps) => {
const [loading, setLoading] = useState(false)
return (
<PrimaryAgentButton
startIcon={<VSCodeInsidersIcon />}
disabled={loading}
onClick={() => {
setLoading(true)
getApiKey()
.then(({ key }) => {
const query = new URLSearchParams({
owner: userName,
workspace: workspaceName,
url: location.origin,
token: key,
})
if (agentName) {
query.set("agent", agentName)
}
if (folderPath) {
query.set("folder", folderPath)
}
location.href = `vscode-insiders://coder.coder-remote/open?${query.toString()}`
})
.catch((ex) => {
console.error(ex)
})
.finally(() => {
setLoading(false)
})
}}
>
VS Code Insiders
</PrimaryAgentButton>
)
}