diff --git a/cmd/frontend/internal/app/ui/handlers.go b/cmd/frontend/internal/app/ui/handlers.go
index 00faefbcc13..6bef8bc7a39 100644
--- a/cmd/frontend/internal/app/ui/handlers.go
+++ b/cmd/frontend/internal/app/ui/handlers.go
@@ -215,9 +215,9 @@ func serveHome(w http.ResponseWriter, r *http.Request) error {
}
if envvar.SourcegraphDotComMode() && !actor.FromContext(r.Context()).IsAuthenticated() {
- // The user is not signed in and tried to access our main site at sourcegraph.com.
- // Redirect to sourcegraph.com/start so they see general info.
- http.Redirect(w, r, "/start", http.StatusTemporaryRedirect)
+ // The user is not signed in and tried to access Sourcegraph.com. Redirect to /welcome so
+ // they see the welcome page.
+ http.Redirect(w, r, "/welcome", http.StatusTemporaryRedirect)
return nil
}
// sourcegraph.com (not about) homepage. There is none, redirect them to /search.
@@ -248,7 +248,7 @@ func serveSignIn(w http.ResponseWriter, r *http.Request) error {
return renderTemplate(w, "app.html", common)
}
-func serveStart(w http.ResponseWriter, r *http.Request) error {
+func serveWelcome(w http.ResponseWriter, r *http.Request) error {
common, err := newCommon(w, r, "Sourcegraph", serveError)
if err != nil {
return err
@@ -258,8 +258,7 @@ func serveStart(w http.ResponseWriter, r *http.Request) error {
}
if !envvar.SourcegraphDotComMode() {
- // The user is signed in and tried to access sourcegraph.com/start,
- // this page should be a 404 under that situation.
+ // The welcome page only exists on Sourcegraph.com.
w.WriteHeader(http.StatusNotFound)
}
return renderTemplate(w, "app.html", common)
diff --git a/cmd/frontend/internal/app/ui/router.go b/cmd/frontend/internal/app/ui/router.go
index 510cf898543..eeac91543e0 100644
--- a/cmd/frontend/internal/app/ui/router.go
+++ b/cmd/frontend/internal/app/ui/router.go
@@ -64,6 +64,7 @@ const (
routeExtensions = "extensions"
routeHelp = "help"
routeExplore = "explore"
+ routeWelcome = "welcome"
// Legacy redirects
routeLegacyLogin = "login"
@@ -113,6 +114,7 @@ func newRouter() *mux.Router {
r.Path("/").Methods("GET").Name(routeHome)
r.PathPrefix("/threads").Methods("GET").Name(routeThreads)
r.Path("/start").Methods("GET").Name(routeStart)
+ r.PathPrefix("/welcome").Methods("GET").Name(routeWelcome)
r.Path("/search").Methods("GET").Name(routeSearch)
r.Path("/search/badge").Methods("GET").Name(routeSearchBadge)
r.Path("/search/searches").Methods("GET").Name(routeSearchSearches)
@@ -185,7 +187,8 @@ func initRouter() {
router := newRouter()
uirouter.Router = router // make accessible to other packages
router.Get(routeHome).Handler(handler(serveHome))
- router.Get(routeStart).Handler(handler(serveStart))
+ router.Get(routeStart).Handler(staticRedirectHandler("/welcome", http.StatusMovedPermanently))
+ router.Get(routeWelcome).Handler(handler(serveWelcome))
router.Get(routeThreads).Handler(handler(serveBasicPageString("Threads - Sourcegraph")))
router.Get(uirouter.RouteSignIn).Handler(handler(serveSignIn))
router.Get(uirouter.RouteSignUp).Handler(handler(serveBasicPageString("Sign up - Sourcegraph")))
diff --git a/go.mod b/go.mod
index 8ebc5727171..961288505c3 100644
--- a/go.mod
+++ b/go.mod
@@ -10,11 +10,9 @@ require (
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73
github.com/coreos/go-semver v0.2.0
- github.com/cosiner/argv v0.0.1 // indirect
github.com/crewjam/saml v0.0.0-20180831135026-ebc5f787b786
github.com/davecgh/go-spew v1.1.1
github.com/daviddengcn/go-colortext v0.0.0-20171126034257-17e75f6184bc
- github.com/derekparker/delve v1.1.0 // indirect
github.com/dghubble/gologin v1.0.2-0.20181013174641-0e442dd5bb73
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/die-net/lrucache v0.0.0-20190123005519-19a39ef22a11
@@ -82,7 +80,6 @@ require (
github.com/neelance/parallel v0.0.0-20160708114440-4de9ce63d14c
github.com/opentracing-contrib/go-stdlib v0.0.0-20190104202730-77df8e8e70b4
github.com/opentracing/opentracing-go v1.0.2
- github.com/peterh/liner v1.1.0 // indirect
github.com/peterhellberg/link v1.0.0
github.com/pkg/errors v0.8.1
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
@@ -118,7 +115,6 @@ require (
github.com/xeonx/timeago v1.0.0-rc3
github.com/zenazn/goji v0.9.0 // indirect
go.uber.org/atomic v1.3.2 // indirect
- golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 // indirect
golang.org/x/crypto v0.0.0-20190104202753-ff983b9c42bc
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e
golang.org/x/oauth2 v0.0.0-20190201180606-99b60b757ec1
diff --git a/go.sum b/go.sum
index ad9152416c2..75726ae1b0e 100644
--- a/go.sum
+++ b/go.sum
@@ -43,8 +43,6 @@ github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73 h1:7CNPV0LWRCa1FNmq
github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/cosiner/argv v0.0.1 h1:2iAFN+sWPktbZ4tvxm33Ei8VY66FPCxdOxpncUGpAXE=
-github.com/cosiner/argv v0.0.1/go.mod h1:p/NrK5tF6ICIly4qwEDsf6VDirFiWWz0FenfYBwJaKQ=
github.com/crewjam/saml v0.0.0-20180831135026-ebc5f787b786 h1:8OVABJfT9iJh/uHeYlk1HWugxt7j50JPwW2uLOV9Yqs=
github.com/crewjam/saml v0.0.0-20180831135026-ebc5f787b786/go.mod h1:w5eu+HNtubx+kRpQL6QFT2F3yIFfYVe6+EzOFVU7Hko=
github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8=
@@ -62,8 +60,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/daviddengcn/go-colortext v0.0.0-20171126034257-17e75f6184bc h1:nqMZEdowWmtK9ysqvFibHJ56mTprkyE5c/6q8ZHwLc0=
github.com/daviddengcn/go-colortext v0.0.0-20171126034257-17e75f6184bc/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
-github.com/derekparker/delve v1.1.0 h1:icd65nMp7s2HiLz6y/6RCVXBdoED3xxYLwX09EMaRCc=
-github.com/derekparker/delve v1.1.0/go.mod h1:pMSZMfp0Nhbm8qdZJkuE/yPGOkLpGXLS1I4poXQpuJU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dhui/dktest v0.3.0 h1:kwX5a7EkLcjo7VpsPQSYJcKGbXBXdjI9FGjuUj1jn6I=
@@ -328,8 +324,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
-github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
@@ -367,8 +361,6 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pelletier/go-toml v1.1.0 h1:cmiOvKzEunMsAxyhXSzpL5Q1CRKpVv0KQsnAIcSEVYM=
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/peterh/liner v1.1.0 h1:f+aAedNJA6uk7+6rXsYBnhdo4Xux7ESLe+kcuVUF5os=
-github.com/peterh/liner v1.1.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/peterhellberg/link v1.0.0 h1:mUWkiegowUXEcmlb+ybF75Q/8D2Y0BjZtR8cxoKhaQo=
github.com/peterhellberg/link v1.0.0/go.mod h1:gtSlOT4jmkY8P47hbTc8PTgiDDWpdPbFYl75keYyBB8=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -504,8 +496,6 @@ go.opencensus.io v0.18.0 h1:Mk5rgZcggtbvtAun5aJzAtjKKN/t0R3jJPlWILlv938=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
-golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
golang.org/x/crypto v0.0.0-20180505025534-4ec37c66abab/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
diff --git a/package.json b/package.json
index 6c289efe9bf..8aa674524d0 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
"@types/babel__core": "7.0.4",
"@types/chai": "4.1.7",
"@types/chai-as-promised": "7.1.0",
+ "@types/classnames": "^2.2.7",
"@types/cpy": "5.1.0",
"@types/d3-axis": "1.0.11",
"@types/d3-scale": "2.1.0",
@@ -174,6 +175,7 @@
"@sqs/jsonc-parser": "^1.0.3",
"abortable-rx": "^1.0.9",
"bootstrap": "^4.1.3",
+ "classnames": "^2.2.6",
"copy-to-clipboard": "^3.0.7",
"d3-axis": "^1.0.7",
"d3-scale": "^2.0.0",
diff --git a/shared/src/actions/ActionsContainer.tsx b/shared/src/actions/ActionsContainer.tsx
index 8d420d4f9ff..0ae76213465 100644
--- a/shared/src/actions/ActionsContainer.tsx
+++ b/shared/src/actions/ActionsContainer.tsx
@@ -10,7 +10,9 @@ import { PlatformContextProps } from '../platform/context'
import { ActionItem, ActionItemProps } from './ActionItem'
import { ActionsState } from './actions'
-export interface ActionsProps extends ExtensionsControllerProps, PlatformContextProps {
+export interface ActionsProps
+ extends ExtensionsControllerProps<'executeCommand' | 'services'>,
+ PlatformContextProps<'forceUpdateTooltip'> {
menu: ContributableMenu
scope?: ContributionScope
actionItemClass?: string
diff --git a/shared/src/commandPalette/CommandList.tsx b/shared/src/commandPalette/CommandList.tsx
index d2834a32807..07954521587 100644
--- a/shared/src/commandPalette/CommandList.tsx
+++ b/shared/src/commandPalette/CommandList.tsx
@@ -14,7 +14,9 @@ import { getContributedActionItems } from '../contributions/contributions'
import { ExtensionsControllerProps } from '../extensions/controller'
import { PlatformContextProps } from '../platform/context'
-interface Props extends ExtensionsControllerProps, PlatformContextProps {
+interface Props
+ extends ExtensionsControllerProps<'services' | 'executeCommand'>,
+ PlatformContextProps<'forceUpdateTooltip'> {
/** The menu whose commands to display. */
menu: ContributableMenu
diff --git a/web/src/Layout.tsx b/web/src/Layout.tsx
index 874932ad60d..772696fff80 100644
--- a/web/src/Layout.tsx
+++ b/web/src/Layout.tsx
@@ -64,8 +64,6 @@ export interface LayoutProps
isLightTheme: boolean
onThemeChange: () => void
- onMainPage: (mainPage: boolean) => void
- isMainPage: boolean
navbarSearchQuery: string
onNavbarQueryChange: (query: string) => void
diff --git a/web/src/SourcegraphWebApp.scss b/web/src/SourcegraphWebApp.scss
index 7ff21ea846e..6435f3f5281 100644
--- a/web/src/SourcegraphWebApp.scss
+++ b/web/src/SourcegraphWebApp.scss
@@ -240,7 +240,6 @@ hr {
@import './global/GlobalAlerts';
@import './global/GlobalDebug';
@import './docSite/DocSitePage';
-@import './search/input/MainPage';
@import './search/input/ScopePage';
@import './search/input/SearchPage';
@import './search/results/SearchResults';
diff --git a/web/src/SourcegraphWebApp.tsx b/web/src/SourcegraphWebApp.tsx
index 706579fb321..bd41bea124b 100644
--- a/web/src/SourcegraphWebApp.tsx
+++ b/web/src/SourcegraphWebApp.tsx
@@ -73,11 +73,6 @@ interface SourcegraphWebAppState extends PlatformContextProps, SettingsCascadePr
*/
isLightTheme: boolean
- /**
- * Whether the user is on MainPage and therefore not logged in
- */
- isMainPage: boolean
-
/**
* The current search query in the navbar.
*/
@@ -108,7 +103,6 @@ export class SourcegraphWebApp extends React.Component ({ isLightTheme: !state.isLightTheme }))
}
- private onMainPage = (mainPage: boolean) => {
- this.setState(() => ({ isMainPage: mainPage }))
- }
-
private onNavbarQueryChange = (navbarSearchQuery: string) => {
this.setState({ navbarSearchQuery })
}
diff --git a/web/src/auth.ts b/web/src/auth.ts
index 57888c87dbe..23b33706b82 100644
--- a/web/src/auth.ts
+++ b/web/src/auth.ts
@@ -53,7 +53,7 @@ export function refreshAuthenticatedUser(): Observable {
)
}
-const initialSiteConfigAuthPublic = window.context.critical['auth.public']
+const initialSiteConfigAuthPublic = window.context ? window.context.critical['auth.public'] : false // default to false in tests
/**
* Whether auth is required to perform any action.
@@ -67,7 +67,7 @@ const initialSiteConfigAuthPublic = window.context.critical['auth.public']
export const authRequired = authenticatedUser.pipe(map(user => user === null && !initialSiteConfigAuthPublic))
// Populate authenticatedUser.
-if (window.context.isAuthenticatedUser) {
+if (window.context && window.context.isAuthenticatedUser) {
refreshAuthenticatedUser()
.toPromise()
.then(() => void 0, err => console.error(err))
diff --git a/web/src/enterprise.scss b/web/src/enterprise.scss
index 911bef6dc75..91c2b8df15d 100644
--- a/web/src/enterprise.scss
+++ b/web/src/enterprise.scss
@@ -3,6 +3,7 @@
@import './SourcegraphWebApp.scss'; // Need .scss extension because of https://github.com/webpack-contrib/sass-loader/issues/556
// Enterprise styles
+@import './enterprise/dotcom/welcome/WelcomeArea';
@import './enterprise/extensions/registry/RegistryArea';
@import './enterprise/extensions/registry/RegistryNewExtensionPage';
@import './enterprise/extensions/extension/RegistryExtensionManagePage';
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeArea.scss b/web/src/enterprise/dotcom/welcome/WelcomeArea.scss
new file mode 100644
index 00000000000..eec25d18b01
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeArea.scss
@@ -0,0 +1 @@
+@import './WelcomeMainPage';
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeArea.tsx b/web/src/enterprise/dotcom/welcome/WelcomeArea.tsx
new file mode 100644
index 00000000000..067067a8cc8
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeArea.tsx
@@ -0,0 +1,91 @@
+import { LoadingSpinner } from '@sourcegraph/react-loading-spinner'
+import H from 'history'
+import ChevronLeftIcon from 'mdi-react/ChevronLeftIcon'
+import MapSearchIcon from 'mdi-react/MapSearchIcon'
+import React from 'react'
+import { Route, RouteComponentProps, Switch } from 'react-router'
+import { Link } from 'react-router-dom'
+import { ExtensionsControllerProps } from '../../../../../shared/src/extensions/controller'
+import * as GQL from '../../../../../shared/src/graphql/schema'
+import { PlatformContextProps } from '../../../../../shared/src/platform/context'
+import { ErrorBoundary } from '../../../components/ErrorBoundary'
+import { HeroPage } from '../../../components/HeroPage'
+import { RouteDescriptor } from '../../../util/contributions'
+import { WelcomeAreaFooter } from './WelcomeAreaFooter'
+
+const NotFoundPage = () =>
+
+export interface WelcomeAreaRoute extends RouteDescriptor {}
+
+export interface WelcomeAreaProps extends ExtensionsControllerProps, PlatformContextProps, RouteComponentProps<{}> {
+ authenticatedUser: GQL.IUser | null
+ isLightTheme: boolean
+ routes: ReadonlyArray
+ location: H.Location
+ history: H.History
+}
+
+export interface WelcomeAreaRouteContext extends WelcomeAreaProps {}
+
+/**
+ * The welcome area, which contains general product information.
+ */
+export class WelcomeArea extends React.PureComponent {
+ public render(): JSX.Element | null {
+ if (!window.context.sourcegraphDotComMode) {
+ return (
+
+ Visit{' '}
+
+ sourcegraph.com/welcome
+ {' '}
+ instead.
+
+ }
+ />
+ )
+ }
+
+ const { children, ...context } = this.props
+ return (
+
+ {this.props.location.pathname !== '/welcome' && (
+
+
+
+ Welcome
+
+
+ )}
+
+ }>
+
+ {this.props.routes.map(
+ ({ path, exact, render, condition = () => true }) =>
+ condition(context) && (
+ (
+ <>
+ {render({ ...context, ...routeComponentProps })}
+
+ >
+ )}
+ />
+ )
+ )}
+
+
+
+
+
+ )
+ }
+}
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeAreaFooter.tsx b/web/src/enterprise/dotcom/welcome/WelcomeAreaFooter.tsx
new file mode 100644
index 00000000000..cb881ad135a
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeAreaFooter.tsx
@@ -0,0 +1,135 @@
+import React from 'react'
+import { Link } from 'react-router-dom'
+
+export const WelcomeAreaFooter: React.FunctionComponent<{ isLightTheme: boolean }> = ({ isLightTheme }) => (
+ <>
+
+
+
+
Features
+
+
+ Code search
+
+
+ Code intelligence
+
+
+ Integrations
+
+
+
+ Enterprise
+
+
+
+
+
+
+
+
+
+
+ Terms
+ {' '}
+ -{' '}
+
+ Privacy
+ {' '}
+ - Copyright © 2018 Sourcegraph, Inc.
+
+ >
+)
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeMainPage.scss b/web/src/enterprise/dotcom/welcome/WelcomeMainPage.scss
new file mode 100644
index 00000000000..35722d18da6
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeMainPage.scss
@@ -0,0 +1,23 @@
+@import './WelcomeMainPageDemos';
+@import './WelcomeMainPageLogos';
+
+.welcome-main-page {
+ &__logo-mark {
+ width: 1.5rem;
+ height: 1.5rem;
+ position: absolute;
+ top: -1.5rem; // make CTAs flush with header text
+ }
+ &__header {
+ font-size: 24px;
+ }
+ &__demo {
+ min-height: 540px; // reduce jitter while page is loading
+ }
+}
+
+.theme-dark .welcome-main-page {
+ &__sign-up {
+ color: #ffffff; // otherwise the signup CTA link text is indistinguishable from text-muted
+ }
+}
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeMainPage.tsx b/web/src/enterprise/dotcom/welcome/WelcomeMainPage.tsx
new file mode 100644
index 00000000000..1cb17e24bef
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeMainPage.tsx
@@ -0,0 +1,157 @@
+import * as H from 'history'
+import CloudUploadIcon from 'mdi-react/CloudUploadIcon'
+import * as React from 'react'
+import { Link } from 'react-router-dom'
+import { ExtensionsControllerProps } from '../../../../../shared/src/extensions/controller'
+import * as GQL from '../../../../../shared/src/graphql/schema'
+import { PlatformContextProps } from '../../../../../shared/src/platform/context'
+import { eventLogger } from '../../../tracking/eventLogger'
+import { WelcomeMainPageDemos } from './WelcomeMainPageDemos'
+import { WelcomeMainPageLogos } from './WelcomeMainPageLogos'
+
+// Lambdas are OK in this component because it is not performance sensitive and using them
+// simplifies the code.
+//
+// tslint:disable:jsx-no-lambda
+
+interface Props extends ExtensionsControllerProps, PlatformContextProps {
+ authenticatedUser: GQL.IUser | null
+ isLightTheme: boolean
+ location: H.Location
+ history: H.History
+}
+
+/**
+ * The welcome main page, which describes Sourcegraph functionality and other general information.
+ */
+export class WelcomeMainPage extends React.Component {
+ public render(): JSX.Element | null {
+ return (
+
+
+
+
+
+
+
+
+ Search, navigate, and review code.
+ {' '}
+ Find answers.
+
+
Sourcegraph is a web-based code search and navigation tool for dev teams.
+
+
+ Code search: fast, cross-repository, on any commit/branch (no
+ indexing delay), with support for regexps, diffs, and{' '}
+
+ filters
+
+
+
+ Code navigation: go-to-definition and find-references for{' '}
+
+ all major languages
+
+
+
+ Deep integrations with GitHub, GitHub Enterprise, GitLab,
+ Bitbucket Server, Phabricator, etc., plus a{' '}
+
+ powerful extension API
+
+
+
+
+ Open-source
+
+ , self-hosted, and free (
+
+ Enterprise
+ {' '}
+ upgrade available)
+
+
+
+
+ See how it's used
+ {' '}
+ to build better software faster at:
+
+
+
+
+ …and thousands of other organizations.
+
+
+
+
+
+
+ {!this.props.authenticatedUser && (
+
+ eventLogger.log('WelcomeSignUpForSourcegraphDotCom')}
+ >
+ Sign up on Sourcegraph.com
+
+
+ A public Sourcegraph instance for public code only.
+
+
+ )}
+
+
+
+
+ VIDEO
+
+
+
+
+ )
+ }
+}
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeMainPageDemos.scss b/web/src/enterprise/dotcom/welcome/WelcomeMainPageDemos.scss
new file mode 100644
index 00000000000..7dfa11c8e7f
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeMainPageDemos.scss
@@ -0,0 +1,13 @@
+.welcome-main-page-demos {
+ &__item {
+ touch-action: manipulation; // remove iOS tap delay
+ }
+ &__video {
+ // To avoid jitter during loading/switching, calculate height of video based on page
+ // dimensions and video aspect ratio.
+ min-height: calc((100vw - (12px * 4)) * (1596 / 2535));
+ @media screen and (min-width: 1000px) {
+ min-height: 550px;
+ }
+ }
+}
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeMainPageDemos.tsx b/web/src/enterprise/dotcom/welcome/WelcomeMainPageDemos.tsx
new file mode 100644
index 00000000000..30c849a5609
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeMainPageDemos.tsx
@@ -0,0 +1,83 @@
+import classnames from 'classnames'
+import H from 'history'
+import PlayCircleOutlineIcon from 'mdi-react/PlayCircleOutlineIcon'
+import React from 'react'
+import { Link } from 'react-router-dom'
+import { eventLogger } from '../../../tracking/eventLogger'
+
+interface Props {
+ className: string
+ location: H.Location
+ history: H.History
+}
+
+const BASE_VIDEO_URL = 'https://storage.googleapis.com/sourcegraph-assets/video/welcome/video'
+
+// The mp4 videos are 2535x1596 at 20fps.
+//
+// To convert videos from mp4 (from kazam) to m4v (for iPhone):
+//
+// ffmpeg -i INPUT_FILE -pix_fmt yuv420p -vf "scale=-2:720:flags=lanczos" -vcodec libx264 -level 3.2 -profile:v main -preset medium -crf 23 -x264-params ref=4 -movflags +faststart OUTPUT_FILE
+//
+// To upload files:
+//
+// gsutil cp -a public-read -r INPUT_FILES gs://sourcegraph-assets/video/welcome/video/
+const VIDEOS: { title: string; hash: string; filename: string }[] = [
+ {
+ title: 'Code navigation',
+ hash: 'code-navigation',
+ filename: 'Welcome-CodeNavigation',
+ },
+ {
+ title: 'Code search',
+ hash: 'code-search',
+ filename: 'Welcome-Search',
+ },
+ {
+ title: 'GitHub integration',
+ hash: 'github-integration',
+ filename: 'Welcome-GitHub',
+ },
+]
+
+export class WelcomeMainPageDemos extends React.PureComponent {
+ public render(): JSX.Element | null {
+ const activeTab = this.props.location.hash.replace(/^#/, '') || VIDEOS[0].hash
+ const video = VIDEOS.find(v => v.hash === activeTab) || VIDEOS[0]
+ return (
+
+
+
+ Demos:
+
+ {VIDEOS.map(({ title, hash }, i) => (
+
+ eventLogger.log('WelcomeMainPageDemosVideo', { hash })}
+ >
+ {title}
+
+
+ ))}
+
+
+
+
+ Demo video playback is not supported on your browser.
+
+
+ )
+ }
+}
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeMainPageLogos.scss b/web/src/enterprise/dotcom/welcome/WelcomeMainPageLogos.scss
new file mode 100644
index 00000000000..fd6692683f2
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeMainPageLogos.scss
@@ -0,0 +1,18 @@
+.welcome-main-page-logos {
+ &__logo {
+ flex: 0 0 auto;
+ &-1 {
+ height: 1.5rem;
+ }
+ &-2 {
+ height: 2rem;
+ // stylelint-disable-next-line declaration-property-unit-whitelist
+ margin-top: 5px; // equalize perceived text baseline of customer logos
+ }
+ &-3 {
+ height: 3.5rem;
+ // stylelint-disable-next-line declaration-property-unit-whitelist
+ margin-top: 6px; // equalize perceived text baseline of customer logos
+ }
+ }
+}
diff --git a/web/src/enterprise/dotcom/welcome/WelcomeMainPageLogos.tsx b/web/src/enterprise/dotcom/welcome/WelcomeMainPageLogos.tsx
new file mode 100644
index 00000000000..0dd36a86d3e
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/WelcomeMainPageLogos.tsx
@@ -0,0 +1,33 @@
+import { shuffle } from 'lodash'
+import React from 'react'
+import { Logo1, Logo2, Logo3 } from './logos'
+
+// Shuffle logos because we love all of them infinitely. :)
+const LOGOS: {
+ component: React.ComponentType<{ className: string; isLightTheme: boolean }>
+ className: string
+}[] = shuffle([
+ {
+ component: Logo1,
+ className: 'welcome-main-page-logos__logo-1 mr-3',
+ },
+ {
+ component: Logo2,
+ className: 'welcome-main-page-logos__logo-2 mr-3',
+ },
+ {
+ component: Logo3,
+ className: 'welcome-main-page-logos__logo-3 mr-3',
+ },
+])
+
+/**
+ * The logos for the welcome main page.
+ */
+export const WelcomeMainPageLogos: React.FunctionComponent<{ isLightTheme: boolean }> = ({ isLightTheme }) => (
+ <>
+ {LOGOS.map(({ component: C, className }, i) => (
+
+ ))}
+ >
+)
diff --git a/web/src/enterprise/dotcom/welcome/logos.tsx b/web/src/enterprise/dotcom/welcome/logos.tsx
new file mode 100644
index 00000000000..23647d1edee
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/logos.tsx
@@ -0,0 +1,133 @@
+import React from 'react'
+
+interface Props {
+ isLightTheme: boolean
+ className: string
+}
+
+// These components are intentionally not named after the companies, to avoid people reusing them
+// and thinking they are the official SVGs for these company logos.
+
+export const Logo1: React.FunctionComponent = ({ isLightTheme, className }) => {
+ const fill = isLightTheme ? '#010202' : 'white'
+ return (
+
+
+
+
+
+
+
+
+ )
+}
+
+export const Logo2: React.FunctionComponent = ({ isLightTheme, className }) => {
+ const fill = isLightTheme ? '#EA0B8C' : 'white'
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+export const Logo3: React.FunctionComponent = ({ isLightTheme, className }) => {
+ // From https://www.yelp.com/brand: "If you need to display the Yelp logo on a white background
+ // be sure to use the version with the grey stroke."
+ const outlineColor = isLightTheme ? '#cccccc' : 'transparent'
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/web/src/enterprise/dotcom/welcome/routes.tsx b/web/src/enterprise/dotcom/welcome/routes.tsx
new file mode 100644
index 00000000000..6aed021482a
--- /dev/null
+++ b/web/src/enterprise/dotcom/welcome/routes.tsx
@@ -0,0 +1,16 @@
+import React from 'react'
+import { WelcomeAreaRoute } from './WelcomeArea'
+const WelcomeMainPage = React.lazy(async () => ({
+ default: (await import('./WelcomeMainPage')).WelcomeMainPage,
+}))
+
+export const welcomeAreaRoutes: ReadonlyArray = [
+ {
+ path: '/',
+ exact: true,
+ // tslint:disable-next-line:jsx-no-lambda
+ render: props => ,
+ },
+ // We will add more pages here soon. The other pages (search, code intel, integrations) were
+ // removed to avoid blocking shipping of the new main welcome page.
+]
diff --git a/web/src/enterprise/routes.tsx b/web/src/enterprise/routes.tsx
index 042f5bf71e8..336ccb19163 100644
--- a/web/src/enterprise/routes.tsx
+++ b/web/src/enterprise/routes.tsx
@@ -1,5 +1,10 @@
import React from 'react'
+import { Redirect } from 'react-router'
import { LayoutRouteProps, routes } from '../routes'
+import { welcomeAreaRoutes } from './dotcom/welcome/routes'
+const WelcomeArea = React.lazy(async () => ({
+ default: (await import('./dotcom/welcome/WelcomeArea')).WelcomeArea,
+}))
const NewProductSubscriptionPageOrRedirectUser = React.lazy(async () => ({
default: (await import('./user/productSubscriptions/NewProductSubscriptionPageOrRedirectUser'))
.NewProductSubscriptionPageOrRedirectUser,
@@ -13,5 +18,14 @@ export const enterpriseRoutes: ReadonlyArray = [
exact: true,
render: props => ,
},
+ {
+ path: '/start',
+ render: () => ,
+ exact: true,
+ },
+ {
+ path: '/welcome',
+ render: props => ,
+ },
...routes,
]
diff --git a/web/src/nav/GlobalNavbar.scss b/web/src/nav/GlobalNavbar.scss
index 433fe42932c..70630b39560 100644
--- a/web/src/nav/GlobalNavbar.scss
+++ b/web/src/nav/GlobalNavbar.scss
@@ -22,19 +22,26 @@
}
&__logo {
- width: 1.5rem;
height: 1.5rem;
- &:hover {
- animation: spin 0.5s ease-in-out 1;
+ &--full {
+ // stylelint-disable-next-line declaration-property-unit-whitelist
+ width: 150px;
+ margin-right: 0.25rem; // full logo image has slightly more spacing on left side
+ }
+ &:not(&--full) {
+ width: 1.5rem;
+ &:hover {
+ animation: spin 0.5s ease-in-out 1;
- @keyframes spin {
- 50% {
- transform: rotate(180deg) scale(1.2);
- }
+ @keyframes spin {
+ 50% {
+ transform: rotate(180deg) scale(1.2);
+ }
- 100% {
- transform: rotate(180deg) scale(1);
+ 100% {
+ transform: rotate(180deg) scale(1);
+ }
}
}
}
diff --git a/web/src/nav/GlobalNavbar.tsx b/web/src/nav/GlobalNavbar.tsx
index addaabe16b8..03f33c02462 100644
--- a/web/src/nav/GlobalNavbar.tsx
+++ b/web/src/nav/GlobalNavbar.tsx
@@ -10,6 +10,7 @@ import { authRequired } from '../auth'
import { KeybindingsProps } from '../keybindings'
import { parseSearchURLQuery } from '../search'
import { SearchNavbarItem } from '../search/input/SearchNavbarItem'
+import { showDotComMarketing } from '../util/features'
import { NavLinks } from './NavLinks'
interface Props extends SettingsCascadeProps, PlatformContextProps, ExtensionsControllerProps, KeybindingsProps {
@@ -70,7 +71,19 @@ export class GlobalNavbar extends React.PureComponent {
}
public render(): JSX.Element | null {
- const logo =
+ let logoSrc: string
+ const showFullLogo = this.props.location.pathname === '/welcome'
+ if (showFullLogo) {
+ logoSrc = this.props.isLightTheme
+ ? '/.assets/img/sourcegraph-light-head-logo.svg'
+ : '/.assets/img/sourcegraph-head-logo.svg'
+ } else {
+ logoSrc = '/.assets/img/sourcegraph-mark.svg'
+ }
+
+ const logo = (
+
+ )
return (
{this.props.lowProfile ? (
@@ -84,8 +97,8 @@ export class GlobalNavbar extends React.PureComponent
{
{logo}
)}
- {!this.state.authRequired && (
-
+ {!this.state.authRequired && this.props.location.pathname !== '/welcome' && (
+
{
)}
>
)}
- {!this.state.authRequired && }
+ {!this.state.authRequired && }
)
}
diff --git a/web/src/nav/NavLinks.test.tsx b/web/src/nav/NavLinks.test.tsx
new file mode 100644
index 00000000000..cc8ace555b9
--- /dev/null
+++ b/web/src/nav/NavLinks.test.tsx
@@ -0,0 +1,84 @@
+import * as H from 'history'
+import { flatten } from 'lodash'
+import React from 'react'
+import { createRenderer } from 'react-test-renderer/shallow'
+import { setLinkComponent } from '../../../shared/src/components/Link'
+import { ExtensionsControllerProps } from '../../../shared/src/extensions/controller'
+import * as GQL from '../../../shared/src/graphql/schema'
+import { SettingsCascadeProps } from '../../../shared/src/settings/settings'
+import { KeybindingsProps } from '../keybindings'
+import { NavLinks } from './NavLinks'
+
+// Renders a human-readable list of the NavLinks' contents so that humans can more easily diff
+// snapshots to see what actually changed.
+const renderShallow = (element: React.ReactElement
): any => {
+ const renderer = createRenderer()
+ renderer.render(element)
+
+ const getDisplayName = (element: React.ReactChild): string | string[] => {
+ if (element === null) {
+ return []
+ } else if (typeof element === 'string' || typeof element === 'number') {
+ return element.toString()
+ } else if (element.type === 'li' && (element.props.children.props.href || element.props.children.props.to)) {
+ return `${element.props.children.props.children} ${element.props.children.props.href ||
+ element.props.children.props.to}`
+ } else if (typeof element.type === 'symbol' || typeof element.type === 'string') {
+ return flatten(React.Children.map(element.props.children, element => getDisplayName(element)))
+ } else {
+ return element.type.displayName || element.type.name || 'Unknown'
+ }
+ }
+
+ return flatten(
+ React.Children.map(renderer.getRenderOutput().props.children, e => getDisplayName(e)).filter(e => !!e)
+ )
+}
+
+describe('NavLinks', () => {
+ setLinkComponent((props: any) => )
+ afterAll(() => setLinkComponent(null as any)) // reset global env for other tests
+ const NOOP_EXTENSIONS_CONTROLLER: ExtensionsControllerProps<
+ 'executeCommand' | 'services'
+ >['extensionsController'] = { executeCommand: async () => void 0, services: {} as any }
+ const NOOP_PLATFORM_CONTEXT = { forceUpdateTooltip: () => void 0 }
+ const KEYBINDINGS: KeybindingsProps['keybindings'] = { commandPalette: [] }
+ const SETTINGS_CASCADE: SettingsCascadeProps['settingsCascade'] = { final: null, subjects: null }
+ // tslint:disable-next-line:no-object-literal-type-assertion
+ const USER = { username: 'u' } as GQL.IUser
+ const history = H.createMemoryHistory({ keyLength: 0 })
+ const commonProps = {
+ extensionsController: NOOP_EXTENSIONS_CONTROLLER,
+ platformContext: NOOP_PLATFORM_CONTEXT,
+ isLightTheme: true,
+ onThemeChange: () => void 0,
+ keybindings: KEYBINDINGS,
+ settingsCascade: SETTINGS_CASCADE,
+ }
+
+ // The 3 main props that affect the desired contents of NavLinks are whether the user is signed
+ // in, whether we're on Sourcegraph.com, and the path. Create snapshots of all permutations.
+ for (const authenticatedUser of [null, USER]) {
+ for (const showDotComMarketing of [false, true]) {
+ for (const path of ['/foo', '/search', '/welcome']) {
+ const name = [
+ authenticatedUser ? 'authed' : 'unauthed',
+ showDotComMarketing ? 'Sourcegraph.com' : 'self-hosted',
+ path,
+ ].join(' ')
+ test(name, () => {
+ expect(
+ renderShallow(
+
+ )
+ ).toMatchSnapshot()
+ })
+ }
+ }
+ }
+})
diff --git a/web/src/nav/NavLinks.tsx b/web/src/nav/NavLinks.tsx
index 5c90d146180..c6a4c3031ba 100644
--- a/web/src/nav/NavLinks.tsx
+++ b/web/src/nav/NavLinks.tsx
@@ -1,27 +1,28 @@
import * as H from 'history'
import * as React from 'react'
-import { Link } from 'react-router-dom'
import { Subscription } from 'rxjs'
import { ActionsNavItems } from '../../../shared/src/actions/ActionsNavItems'
import { ContributableMenu } from '../../../shared/src/api/protocol'
import { CommandListPopoverButton } from '../../../shared/src/commandPalette/CommandList'
+import { Link } from '../../../shared/src/components/Link'
import { ExtensionsControllerProps } from '../../../shared/src/extensions/controller'
import * as GQL from '../../../shared/src/graphql/schema'
import { PlatformContextProps } from '../../../shared/src/platform/context'
import { SettingsCascadeProps } from '../../../shared/src/settings/settings'
import { isDiscussionsEnabled } from '../discussions'
import { KeybindingsProps } from '../keybindings'
-import { eventLogger } from '../tracking/eventLogger'
-import { showDotComMarketing } from '../util/features'
import { UserNavItem } from './UserNavItem'
-interface Props extends SettingsCascadeProps, PlatformContextProps, ExtensionsControllerProps, KeybindingsProps {
+interface Props
+ extends SettingsCascadeProps,
+ KeybindingsProps,
+ ExtensionsControllerProps<'executeCommand' | 'services'>,
+ PlatformContextProps<'forceUpdateTooltip'> {
location: H.Location
- history: H.History
authenticatedUser: GQL.IUser | null
isLightTheme: boolean
onThemeChange: () => void
- isMainPage?: boolean
+ showDotComMarketing: boolean
}
export class NavLinks extends React.PureComponent {
@@ -31,24 +32,28 @@ export class NavLinks extends React.PureComponent {
this.subscriptions.unsubscribe()
}
- private onClickInstall = (): void => {
- eventLogger.log('InstallSourcegraphServerCTAClicked', {
- location_on_page: 'Navbar',
- })
- }
-
public render(): JSX.Element | null {
return (
- {showDotComMarketing && (
+ {/* Show "Search" link on small screens when GlobalNavbar hides the SearchNavbarItem. */}
+ {this.props.location.pathname !== '/search' && this.props.location.pathname !== '/welcome' && (
+
+
+ Search
+
+
+ )}
+ {this.props.showDotComMarketing && this.props.location.pathname !== '/welcome' && (
-
- Install Sourcegraph
+
+ Welcome
+
+
+ )}
+ {this.props.showDotComMarketing && this.props.location.pathname === '/welcome' && (
+
+
+ Docs
)}
@@ -59,18 +64,24 @@ export class NavLinks extends React.PureComponent {
platformContext={this.props.platformContext}
location={this.props.location}
/>
-
-
- Explore
-
-
+ {(!this.props.showDotComMarketing ||
+ !!this.props.authenticatedUser ||
+ this.props.location.pathname !== '/welcome') && (
+
+
+ Explore
+
+
+ )}
{!this.props.authenticatedUser && (
<>
-
-
- Extensions
-
-
+ {this.props.location.pathname !== '/welcome' && (
+
+
+ Extensions
+
+
+ )}
{this.props.location.pathname !== '/sign-in' && (
@@ -78,33 +89,37 @@ export class NavLinks extends React.PureComponent {
)}
- {showDotComMarketing && (
+ {this.props.showDotComMarketing && (
About
)}
-
-
- Help
-
-
+ {this.props.location.pathname !== '/welcome' && (
+
+
+ Help
+
+
+ )}
>
)}
-
+ {this.props.location.pathname !== '/welcome' && (
+
+ )}
{this.props.authenticatedUser && (
diff --git a/web/src/nav/UserNavItem.tsx b/web/src/nav/UserNavItem.tsx
index b253d83b843..528b908f13f 100644
--- a/web/src/nav/UserNavItem.tsx
+++ b/web/src/nav/UserNavItem.tsx
@@ -11,7 +11,6 @@ interface Props {
authenticatedUser: GQL.IUser
isLightTheme: boolean
onThemeChange: () => void
- isMainPage?: boolean
showAbout: boolean
showDiscussions: boolean
}
diff --git a/web/src/nav/__snapshots__/NavLinks.test.tsx.snap b/web/src/nav/__snapshots__/NavLinks.test.tsx.snap
new file mode 100644
index 00000000000..14fa222501f
--- /dev/null
+++ b/web/src/nav/__snapshots__/NavLinks.test.tsx.snap
@@ -0,0 +1,125 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`NavLinks authed Sourcegraph.com /foo 1`] = `
+Array [
+ "Search /search",
+ "Welcome /welcome",
+ "ActionsNavItems",
+ "Explore /explore",
+ "CommandListPopoverButton",
+ "UserNavItem",
+]
+`;
+
+exports[`NavLinks authed Sourcegraph.com /search 1`] = `
+Array [
+ "Welcome /welcome",
+ "ActionsNavItems",
+ "Explore /explore",
+ "CommandListPopoverButton",
+ "UserNavItem",
+]
+`;
+
+exports[`NavLinks authed Sourcegraph.com /welcome 1`] = `
+Array [
+ "Docs https://docs.sourcegraph.com",
+ "ActionsNavItems",
+ "Explore /explore",
+ "UserNavItem",
+]
+`;
+
+exports[`NavLinks authed self-hosted /foo 1`] = `
+Array [
+ "Search /search",
+ "ActionsNavItems",
+ "Explore /explore",
+ "CommandListPopoverButton",
+ "UserNavItem",
+]
+`;
+
+exports[`NavLinks authed self-hosted /search 1`] = `
+Array [
+ "ActionsNavItems",
+ "Explore /explore",
+ "CommandListPopoverButton",
+ "UserNavItem",
+]
+`;
+
+exports[`NavLinks authed self-hosted /welcome 1`] = `
+Array [
+ "ActionsNavItems",
+ "Explore /explore",
+ "UserNavItem",
+]
+`;
+
+exports[`NavLinks unauthed Sourcegraph.com /foo 1`] = `
+Array [
+ "Search /search",
+ "Welcome /welcome",
+ "ActionsNavItems",
+ "Explore /explore",
+ "Extensions /extensions",
+ "Sign in /sign-in",
+ "About https://about.sourcegraph.com",
+ "Help /help",
+ "CommandListPopoverButton",
+]
+`;
+
+exports[`NavLinks unauthed Sourcegraph.com /search 1`] = `
+Array [
+ "Welcome /welcome",
+ "ActionsNavItems",
+ "Explore /explore",
+ "Extensions /extensions",
+ "Sign in /sign-in",
+ "About https://about.sourcegraph.com",
+ "Help /help",
+ "CommandListPopoverButton",
+]
+`;
+
+exports[`NavLinks unauthed Sourcegraph.com /welcome 1`] = `
+Array [
+ "Docs https://docs.sourcegraph.com",
+ "ActionsNavItems",
+ "Sign in /sign-in",
+ "About https://about.sourcegraph.com",
+]
+`;
+
+exports[`NavLinks unauthed self-hosted /foo 1`] = `
+Array [
+ "Search /search",
+ "ActionsNavItems",
+ "Explore /explore",
+ "Extensions /extensions",
+ "Sign in /sign-in",
+ "Help /help",
+ "CommandListPopoverButton",
+]
+`;
+
+exports[`NavLinks unauthed self-hosted /search 1`] = `
+Array [
+ "ActionsNavItems",
+ "Explore /explore",
+ "Extensions /extensions",
+ "Sign in /sign-in",
+ "Help /help",
+ "CommandListPopoverButton",
+]
+`;
+
+exports[`NavLinks unauthed self-hosted /welcome 1`] = `
+Array [
+ "ActionsNavItems",
+ "Explore /explore",
+ "Sign in /sign-in",
+]
+`;
diff --git a/web/src/routes.tsx b/web/src/routes.tsx
index dc4c7ca8fdc..364ba5e3c10 100644
--- a/web/src/routes.tsx
+++ b/web/src/routes.tsx
@@ -2,9 +2,6 @@ import * as React from 'react'
import { Redirect, RouteComponentProps } from 'react-router'
import { LayoutProps } from './Layout'
import { parseSearchURLQuery } from './search'
-const MainPage = React.lazy(async () => ({
- default: (await import('./search/input/MainPage')).MainPage,
-}))
const SearchPage = React.lazy(async () => ({
default: (await import('./search/input/SearchPage')).SearchPage,
}))
@@ -78,12 +75,11 @@ export const routes: ReadonlyArray = [
{
path: '/',
render: (props: any) =>
- window.context.sourcegraphDotComMode && !props.user ? : ,
- exact: true,
- },
- {
- path: '/start',
- render: (props: any) => ,
+ window.context.sourcegraphDotComMode && !props.user ? (
+
+ ) : (
+
+ ),
exact: true,
},
{
diff --git a/web/src/search/input/CodeIntellifyBlob.tsx b/web/src/search/input/CodeIntellifyBlob.tsx
deleted file mode 100644
index 8c24255a81f..00000000000
--- a/web/src/search/input/CodeIntellifyBlob.tsx
+++ /dev/null
@@ -1,353 +0,0 @@
-import { createHoverifier, findPositionsFromEvents, HoveredToken, HoverState } from '@sourcegraph/codeintellify'
-import { getTokenAtPosition } from '@sourcegraph/codeintellify/lib/token_position'
-import { Position } from '@sourcegraph/extension-api-types'
-import * as H from 'history'
-import * as React from 'react'
-import { Subject, Subscription } from 'rxjs'
-import { catchError, filter, map, withLatestFrom } from 'rxjs/operators'
-import { ActionItemProps } from '../../../../shared/src/actions/ActionItem'
-import { HoverMerged } from '../../../../shared/src/api/client/types/hover'
-import { ExtensionsControllerProps } from '../../../../shared/src/extensions/controller'
-import * as GQL from '../../../../shared/src/graphql/schema'
-import { getHoverActions } from '../../../../shared/src/hover/actions'
-import { HoverContext, HoverOverlay } from '../../../../shared/src/hover/HoverOverlay'
-import { getModeFromPath } from '../../../../shared/src/languages'
-import { PlatformContextProps } from '../../../../shared/src/platform/context'
-import { ErrorLike, isErrorLike } from '../../../../shared/src/util/errors'
-import { isDefined, propertyIsDefined } from '../../../../shared/src/util/types'
-import { FileSpec, ModeSpec, PositionSpec, RepoSpec, ResolvedRevSpec, RevSpec } from '../../../../shared/src/util/url'
-import { getHover } from '../../backend/features'
-import { fetchBlob } from '../../repo/blob/BlobPage'
-
-interface Props extends ExtensionsControllerProps, PlatformContextProps {
- history: H.History
- location: H.Location
- className: string
- startLine: number
- endLine: number
- parentElement: string
-
- overlayPortal?: HTMLElement
- tooltipClass: string
- defaultHoverPosition: Position
-}
-
-interface State extends HoverState {
- /**
- * The blob data or error that happened.
- * undefined while loading.
- */
- blobOrError?: GQL.IGitBlob | ErrorLike
- target?: EventTarget
-}
-
-const domFunctions = {
- getCodeElementFromTarget: (target: HTMLElement): HTMLTableCellElement | null => {
- // If the target is part of the decoration, return null.
- if (
- target.classList.contains('line-decoration-attachment') ||
- target.classList.contains('line-decoration-attachment__contents')
- ) {
- return null
- }
-
- const row = target.closest('tr')
- if (!row) {
- return null
- }
-
- return row.cells[1]
- },
- getCodeElementFromLineNumber: (codeView: HTMLElement, line: number): HTMLElement | null => {
- const lineNumberElement = codeView.querySelector(`td[data-line="${line}"]`)
-
- if (!lineNumberElement) {
- return null
- }
- return lineNumberElement.nextElementSibling as HTMLElement | null
- },
- getLineNumberFromCodeElement: (codeCell: HTMLElement): number => {
- const row = codeCell.closest('tr')
- if (!row) {
- throw new Error('Could not find closest row for codeCell')
- }
- const numberCell = row.cells[0]
- if (!numberCell || !numberCell.dataset.line) {
- throw new Error('Could not find line number')
- }
- return parseInt(numberCell.dataset.line, 10)
- },
-}
-
-const REPO_NAME = 'github.com/gorilla/mux'
-const COMMIT_ID = '9e1f5955c0d22b55d9e20d6faa28589f83b2faca'
-const REV = undefined
-const FILE_PATH = 'mux.go'
-
-export class CodeIntellifyBlob extends React.Component {
- /** Emits whenever the ref callback for the code element is called */
- private codeViewElements = new Subject()
- private nextCodeViewElement = (element: HTMLElement | null) => this.codeViewElements.next(element)
-
- /** Emits whenever the ref callback for the hover element is called */
- private hoverOverlayElements = new Subject()
- private nextOverlayElement = (element: HTMLElement | null) => this.hoverOverlayElements.next(element)
-
- /** Emits whenever the ref callback for the demo file element is called */
- private codeIntellifyBlobElements = new Subject()
- private nextCodeIntellifyBlobElements = (element: HTMLElement | null) =>
- this.codeIntellifyBlobElements.next(element)
-
- /** Emits when the close button was clicked */
- private closeButtonClicks = new Subject()
- private nextCloseButtonClick = (event: MouseEvent) => this.closeButtonClicks.next(event)
-
- private subscriptions = new Subscription()
-
- private componentUpdates = new Subject()
-
- private target: EventTarget | null = null
-
- constructor(props: Props) {
- super(props)
- this.state = {}
-
- const hoverifier = createHoverifier<
- RepoSpec & RevSpec & FileSpec & ResolvedRevSpec,
- HoverMerged,
- ActionItemProps
- >({
- closeButtonClicks: this.closeButtonClicks,
- hoverOverlayElements: this.hoverOverlayElements,
- hoverOverlayRerenders: this.componentUpdates.pipe(
- withLatestFrom(this.hoverOverlayElements, this.codeIntellifyBlobElements),
- map(([, hoverOverlayElement, codeIntellifyBlobElement]) => ({
- hoverOverlayElement,
- codeIntellifyBlobElement,
- })),
- filter(propertyIsDefined('codeIntellifyBlobElement')),
- map(({ hoverOverlayElement, codeIntellifyBlobElement }) => ({
- hoverOverlayElement,
- relativeElement: codeIntellifyBlobElement.closest(this.props.parentElement) as HTMLElement | null,
- })),
- // Can't reposition HoverOverlay or file weren't rendered
- filter(propertyIsDefined('relativeElement')),
- filter(propertyIsDefined('hoverOverlayElement'))
- ),
- getHover: hoveredToken => getHover(this.getLSPTextDocumentPositionParams(hoveredToken), this.props),
- getActions: context => getHoverActions(this.props, context),
- })
-
- this.subscriptions.add(hoverifier)
- const positionEvents = this.codeViewElements.pipe(
- filter(isDefined),
- findPositionsFromEvents(domFunctions)
- )
-
- const targets = positionEvents.pipe(map(({ event: { target } }) => target))
-
- targets.subscribe(target => (this.target = target))
-
- this.subscriptions.add(
- hoverifier.hoverify({
- positionEvents,
- resolveContext: () => ({
- repoName: REPO_NAME,
- commitID: COMMIT_ID,
- rev: REV || '',
- filePath: FILE_PATH,
- }),
- dom: domFunctions,
- })
- )
-
- this.subscriptions.add(hoverifier.hoverStateUpdates.subscribe(update => this.setState(update)))
-
- this.subscriptions.add(
- this.codeViewElements
- .pipe(
- filter(isDefined),
- map(codeView => getTokenAtPosition(codeView, props.defaultHoverPosition, domFunctions)),
- filter(isDefined)
- )
- .subscribe(token => {
- const showOnHomepage = props.className === 'code-intellify-container' && window.innerWidth >= 1393
- const showOnModal =
- props.className === 'code-intellify-container-modal' && window.innerWidth >= 1275
- if (showOnHomepage || showOnModal) {
- token.click()
- }
- })
- )
- }
-
- public componentDidMount(): void {
- // Fetch repository revision.
- fetchBlob({
- repoName: REPO_NAME,
- commitID: COMMIT_ID,
- filePath: FILE_PATH,
- isLightTheme: false,
- disableTimeout: false,
- })
- .pipe(
- catchError(error => {
- console.error(error)
- return [error]
- })
- )
- .subscribe(blobOrError => this.setState({ blobOrError }), err => console.error(err))
-
- this.componentUpdates.next()
-
- this.subscriptions.add(
- this.props.extensionsController.services.model.model.next({
- ...this.props.extensionsController.services.model.model.value,
- visibleViewComponents: [
- {
- type: 'textEditor',
- item: {
- uri: `git://github.com/gorilla/mux?9e1f5955c0d22b55d9e20d6faa28589f83b2faca#mux.go`,
- languageId: 'go',
- text: '',
- },
- selections: [],
- isActive: true,
- },
- ],
- })
- )
- }
-
- public componentDidUpdate(): void {
- this.componentUpdates.next()
- }
-
- private getLSPTextDocumentPositionParams(
- position: HoveredToken & RepoSpec & RevSpec & FileSpec & ResolvedRevSpec
- ): RepoSpec & RevSpec & ResolvedRevSpec & FileSpec & PositionSpec & ModeSpec {
- return {
- repoName: position.repoName,
- filePath: position.filePath,
- commitID: position.commitID,
- rev: position.rev,
- mode: getModeFromPath(FILE_PATH),
- position,
- }
- }
-
- public render(): JSX.Element {
- if (!this.state.blobOrError) {
- // Render placeholder for layout before content is fetched.
- return Loading...
- }
-
- const hoverOverlayProps = this.adjustHoverOverlayPosition(this.target)
-
- return (
-
-
- {!isErrorLike(this.state.blobOrError) && (
-
- )}
- {this.state.hoverOverlayProps && (
-
- )}
-
- )
- }
- /**
- * This function adjusts the position of the hoverOverlay so that it does not overflow on the right side
- * of the viewport. If a hoverOverlay will exceed the viewport, this function will adjust the position
- * so that it aligns the right side of the hover overlay with the right side of the target element.
- *
- */
- private adjustHoverOverlayPosition(
- target: EventTarget | null
- ): HoverState['hoverOverlayProps'] {
- const viewPortEdge = window.innerWidth
- if (!this.state.hoverOverlayProps) {
- return undefined
- }
- if (!target) {
- return this.state.hoverOverlayProps
- }
- const { overlayPosition, ...rest } = this.state.hoverOverlayProps
-
- const targetBounds = (target as HTMLElement).getBoundingClientRect()
- let newOverlayPosition: { top: number; left: number } = overlayPosition!
-
- if (overlayPosition && viewPortEdge < targetBounds.left + 512 && targetBounds.right - 512 >= 0) {
- const containerWidth = (document.querySelector(
- this.props.parentElement
- ) as HTMLElement).parentElement!.getBoundingClientRect().width
-
- const parentWidth = (document.querySelector(
- this.props.parentElement
- ) as HTMLElement).getBoundingClientRect().width
-
- // One side of the total horizontal margin.
- const halfMarginWidth = (viewPortEdge - containerWidth) / 2
- // The difference between the viewport width and parent width. We need to subtract this because
- // `left` is relative to the parent, whereas targetBounds.right is relative to the viewport.
- const relativeElementDifference = viewPortEdge - parentWidth
-
- newOverlayPosition = {
- top: overlayPosition.top,
- // 512 is the width of a hoverOverlay.
- left: targetBounds.right - 512 - relativeElementDifference + halfMarginWidth,
- }
- }
- return { ...rest, overlayPosition: newOverlayPosition }
- }
-}
-
-/**
- * We can only fetch blobs as an entire file. For demo purposes, we only want to show part of the file.
- * This function trims the HTML string of the file that will be code-intellfied on the homepage to only show
- * the lines that we specify. It makes some assumptions for this specific use case, such as the presence
- * of a single table and tbody element in the html, so be careful when changing.
- */
-function trimHTMLString(html: string, startLine: number, endLine: number): string {
- const domParser = new DOMParser()
- const doc = domParser.parseFromString(html, 'text/html')
- const startToRemove = doc.querySelectorAll(`tr:nth-child(n + 0):nth-child(-n + ${startLine})`)
- const endToRemove = doc.querySelectorAll(`tr:nth-child(n + ${endLine})`)
-
- const elementsToRemove = [...startToRemove, ...endToRemove]
- const tableEl = doc.querySelector('tbody')! // assume a single tbody element will exist in blob HTML
-
- for (const el of elementsToRemove) {
- tableEl.removeChild(el)
- }
-
- const xmlSerializer = new XMLSerializer()
- const tbl = doc.querySelector('table')! // assume a single table element will exist in blob HTML
- const trimmedHTMLString = xmlSerializer.serializeToString(tbl)
-
- return trimmedHTMLString
-}
diff --git a/web/src/search/input/MainPage.scss b/web/src/search/input/MainPage.scss
deleted file mode 100644
index da1d2c4f12b..00000000000
--- a/web/src/search/input/MainPage.scss
+++ /dev/null
@@ -1,1080 +0,0 @@
-// Stylelint rules
-// stylelint-disable value-no-vendor-prefix
-// Webkit prefixes are needed
-// stylelint-disable color-named
-// stylelint-disable color-hex-length
-// RGBA is prefered in some CSS properties and hex length should be consistant.
-
-@import '../../nav/GlobalNavbar';
-@import './SearchFilterChips';
-@import './QueryInput';
-@import './QueryInputForModal';
-@import '../saved-queries/SavedQueries';
-
-body.modal-open {
- overflow: hidden !important;
- max-height: 100%;
-}
-body.main-page {
- .nav-links {
- @media screen and (max-width: $media-md) {
- display: none !important;
- }
- @media screen and (max-height: 420px) {
- display: none !important;
- }
- }
- .query-input2__suggestions,
- .query-input2-for-modal__suggestions {
- overflow-y: auto !important;
- overflow-x: hidden !important;
- ul {
- li {
- overflow: hidden !important;
- }
- }
- }
- .query-input2-for-modal__suggestions {
- .query-input2__loading-notifier {
- top: 1rem;
- }
- }
- .hover-overlay__content.hover-overlay__row {
- p {
- font-size: 14px !important;
- }
- }
-}
-.main-page {
- // Colors to match about.sourcegraph.com
- $light-2: #7a8fb8;
- $light-6: #afbcd4;
- $light-11: #f2f4f8;
- $dark-1: #566e9f;
- $dark-4: #405377;
- $dark-11: #0e121b;
- // Viewport breakpoints to match about.sourcegraph.com
- $media-sm: 576px;
- $media-md: 768px;
- $media-lg: 992px;
- width: 100%;
- display: block;
-
- &__logo {
- flex: 0 0 auto;
- display: flex;
- align-items: center;
- width: 20rem;
- margin-top: 6rem;
- max-width: 90%;
- }
-
- &__container {
- width: 100%;
- margin-top: 4rem;
- position: relative;
- }
-
- &__input-container {
- width: 100%;
- display: flex;
- }
-
- &__input-sub-container {
- width: 100%;
- display: block;
- margin-top: 0.5rem;
- margin-bottom: 2rem;
- }
-
- &__query-container {
- flex: 0 0 auto;
- width: 49rem;
- max-width: 90%;
- position: relative;
- }
- @media screen and (max-width: 500px) {
- .btn-primary,
- .btn-secondary {
- width: 100%;
- }
- }
- .hero-section {
- width: 100%;
- position: sticky;
- position: -webkit-sticky;
- @media screen and (min-height: 650px) and (min-width: 376px) {
- top: 44px;
- }
- z-index: 1;
-
- &__bg {
- background: #08335f;
- background: linear-gradient(20deg, #08335f 0%, #000000 65%);
- position: fixed;
- z-index: -1;
- top: 0;
- width: 100%;
- height: 100%;
- }
- .hero-container {
- width: 100%;
- padding-right: 0.75rem;
- padding-left: 0.75rem;
- margin-right: auto;
- margin-left: auto;
- // stylelint-disable-next-line declaration-property-unit-whitelist
- padding-top: 15vh;
- padding-bottom: 10rem;
- min-height: calc(70vh - 8rem);
- @media screen and (max-width: $media-md) {
- padding-top: 2rem;
- padding-bottom: 4rem;
- min-height: calc(100vh - 8rem);
- .row {
- // stylelint-disable-next-line declaration-property-unit-whitelist
- margin-top: 5vh;
- }
- }
- @media screen and (max-width: 800px) and (max-height: 420px) {
- padding-top: 2rem;
- padding-bottom: 4rem;
- min-height: calc(100vh - 8rem);
- .row {
- // stylelint-disable-next-line declaration-property-unit-whitelist
- margin-top: 10vh;
- }
- }
- h1 {
- font-size: 54px;
- line-height: normal;
- margin-top: -0.75rem;
-
- background: radial-gradient(closest-side, #019fde, #b200f8, #f96216);
- background-size: 600% 600%;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- -webkit-animation: bg-animation 90s ease infinite;
- animation: bg-animation 90s ease infinite;
-
- @keyframes bg-animation {
- 0% {
- background-position: 0% 17%;
- }
- 50% {
- background-position: 90% 84%;
- }
- 100% {
- background-position: 0% 17%;
- }
- }
- }
-
- h2 {
- font-size: 22px;
- font-weight: 400;
- margin-bottom: 0;
- }
- p {
- font-size: 16px;
- padding-right: 2rem;
- }
- .btn {
- margin-right: 1rem;
- margin-bottom: 1rem;
- }
- .btn-primary {
- border: none;
- }
- }
- .hover-overlay__actions,
- .hover-overlay__action {
- .btn {
- margin: 0;
- }
- }
- }
- .company-logos {
- background-color: #151c28;
- position: sticky;
- position: -webkit-sticky;
- @media screen and (max-width: 800px) and (max-height: 420px) {
- padding-top: 2rem;
- padding-bottom: 3rem;
- // stylelint-disable-next-line declaration-property-unit-whitelist
- min-height: calc(100vh - 8rem);
- .row {
- // stylelint-disable-next-line declaration-property-unit-whitelist
- margin-top: calc(50vh - 60%);
- }
- }
- z-index: 2;
- box-shadow: rgba(0, 0, 0, 0.35) 0 4rem 8rem 12rem;
- padding-top: 1rem;
- padding-bottom: 1rem;
- width: 100%;
- h2 {
- text-align: center;
- font-size: 24px;
- font-weight: 500;
- margin-bottom: 0;
- }
- p {
- font-size: 16px;
- padding-right: 2rem;
- }
- .row {
- padding-top: 2rem;
- padding-bottom: 0;
- }
-
- .logo {
- padding: 2rem 0;
-
- &-image {
- width: 100%;
- background-position: center;
- background-repeat: no-repeat;
- background-size: contain;
- // stylelint-disable-next-line declaration-property-unit-whitelist
- height: 115px;
- }
- }
- .logo4 {
- background-image: url('data:image/png;base64,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HJAAAAAACPr/uh2BCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALwFlnlxUdZntPcAAAAASUVORK5CYII=');
- }
- .logo3 {
- background-image: url('data:image/png;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/24PDggAAAAAhPx/3ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcBAjDGzGrG24oAAAAASUVORK5CYII=');
- }
- .logo2 {
- background-image: url('data:image/png;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADr7/8ARpnJnFGQlHgAAAAASUVORK5CYII=');
- }
- .logo1 {
- background-image: url('data:image/png;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACw1f4/fnA/REmHEOcAAAAASUVORK5CYII=');
- }
- }
- .about-section {
- position: sticky;
- position: -webkit-sticky;
- @media screen and (max-width: 800px) and (max-height: 420px) {
- padding-top: 4rem;
- padding-bottom: 4rem;
- // stylelint-disable-next-line declaration-property-unit-whitelist
- min-height: calc(100vh - 8rem);
- .row {
- // stylelint-disable-next-line declaration-property-unit-whitelist
- margin-top: calc(50vh - 60%);
- }
- }
- @media screen and (min-width: $media-md) and (min-height: 420px) {
- top: 0;
- }
- &:nth-of-type(2) {
- h1 {
- padding-bottom: 1.5rem;
- display: inline-block;
- -webkit-border-image: -webkit-gradient(
- linear,
- left top,
- right top,
- from(#00b3f8),
- to(#7042f8),
- color-stop(0%, #00b3f8),
- color-stop(100%, #7042f8)
- )
- 0 0 4 0 repeat repeat;
- border-image: -webkit-gradient(
- linear,
- left top,
- right top,
- from(#00b3f8),
- to(#7042f8),
- color-stop(0%, #00b3f8),
- color-stop(50%, #7042f8)
- )
- 0 0 4 0 repeat repeat;
- border-bottom: 4px solid;
- }
- }
- &:nth-of-type(3) {
- h1 {
- padding-bottom: 1.5rem;
- display: inline-block;
- -webkit-border-image: -webkit-gradient(
- linear,
- left top,
- right top,
- from(#dc3876),
- to(#9121f9),
- color-stop(0%, #dc3876),
- color-stop(100%, #9121f9)
- )
- 0 0 4 0 repeat repeat;
- border-image: -webkit-gradient(
- linear,
- left top,
- right top,
- from(#dc3876),
- to(#9121f9),
- color-stop(0%, #dc3876),
- color-stop(100%, #9121f9)
- )
- 0 0 4 0 repeat repeat;
- border-bottom: 4px solid;
- }
- }
- &:nth-of-type(4) {
- h1 {
- padding-bottom: 1.5rem;
- display: inline-block;
- -webkit-border-image: -webkit-gradient(
- linear,
- left top,
- right top,
- from(#dc3876),
- to(#9121f9),
- color-stop(0%, #dc3876),
- color-stop(100%, #9121f9)
- )
- 0 0 4 0 repeat repeat;
- border-image: -webkit-gradient(
- linear,
- left top,
- right top,
- from(#f85f1b),
- to(#0fd5f8),
- color-stop(0%, #f85f1b),
- color-stop(67%, #d9367b),
- color-stop(84%, #8b27f9),
- color-stop(100%, #0fd5f8)
- )
- 0 0 4 0 repeat repeat;
- border-bottom: 4px solid;
- }
- }
-
- h1 {
- font-size: 54px;
- padding-top: 0;
- @media screen and (max-width: $media-md) {
- line-height: normal;
- }
- }
- h2 {
- font-size: 22px;
- font-weight: 400;
- margin-bottom: 0;
- padding-left: 0.25rem;
- }
- p {
- font-size: 16px;
- padding-right: 2rem;
- }
- .row {
- padding-top: 12rem;
- padding-bottom: 8rem;
- }
- // stylelint-disable-next-line declaration-block-no-duplicate-properties
- position: sticky;
- // stylelint-disable-next-line declaration-block-no-duplicate-properties
- position: -webkit-sticky;
- z-index: 2;
- box-shadow: rgba(0, 0, 0, 0.35) 0 4rem 8rem 12rem;
- // stylelint-disable-next-line no-duplicate-selectors
- &:nth-of-type(2) {
- box-shadow: none;
- }
- padding-top: 2rem;
- padding-bottom: 4rem;
- background-color: #000000;
- width: 100%;
- }
- .up-next-section {
- h1 {
- font-size: 54px;
- padding-top: 0;
- color: #1e232e;
- @media screen and (max-width: $media-md) {
- line-height: normal;
- }
- }
- h2 {
- font-size: 22px;
- font-weight: 400;
- margin-bottom: 0;
- color: #000000;
- }
- p {
- font-size: 16px;
- padding-right: 2rem;
- color: #000000;
- }
- .btn {
- margin-right: 1rem;
- margin-bottom: 1rem;
- }
- .col-md-12 {
- padding-bottom: 2rem;
- @media screen and (min-width: $media-md) {
- padding-bottom: 6rem;
- }
- @media screen and (min-height: 420px) {
- padding-bottom: 6rem;
- }
- }
- position: sticky;
- position: -webkit-sticky;
- z-index: 3;
- padding-top: 2rem;
- padding-bottom: 4rem;
- background: #e6ebf3;
- width: 100%;
- .row {
- padding-top: 12rem;
- padding-bottom: 8rem;
- }
- }
- .blog-callout {
- h1,
- h2,
- p {
- color: #fafcff;
- }
- p a {
- color: #fafcfe;
- text-decoration: underline;
- }
- .row {
- padding-top: 1.5rem;
- padding-bottom: 0.5rem;
- }
- background: #f96216;
- background: -moz-radial-gradient(
- center,
- ellipse cover,
- rgba(249, 98, 22, 1) 0%,
- rgba(178, 0, 248, 1) 51%,
- rgba(1, 159, 222, 1) 100%
- );
- background: -webkit-radial-gradient(
- center,
- ellipse cover,
- rgba(249, 98, 22, 1) 0%,
- rgba(178, 0, 248, 1) 51%,
- rgba(1, 159, 222, 1) 100%
- );
- background: radial-gradient(
- ellipse at center,
- rgba(249, 98, 22, 1) 0%,
- rgba(178, 0, 248, 1) 51%,
- rgba(1, 159, 222, 1) 100%
- );
- background-size: 200% 800%;
- background-position: calc(100vw * 1) calc(100vh * 1.15);
- }
- .modal-search,
- .modal-intelligence,
- .modal-integrations {
- .btn-close-top {
- width: 2.5rem;
- height: 2.5rem;
- margin-right: 1rem;
- border-radius: 50%;
- border: none;
- background-color: #222222;
- color: #fafafa;
- position: absolute;
- right: 0;
- cursor: pointer;
- z-index: 9999;
- padding: 0;
- }
- .btn-close-bottom {
- height: 2.5rem;
- border-radius: 1.5rem;
- border: none;
- background-color: #333333;
- color: #fafafa;
- position: absolute;
- right: calc(50% - 53px);
- bottom: 3rem;
- cursor: pointer;
- z-index: 9999;
- font-size: 16px;
- padding-left: 1.4rem;
- padding-right: 1rem;
- padding-top: 0.25rem;
- svg {
- // stylelint-disable-next-line declaration-property-unit-whitelist
- margin-top: -2px;
- }
- }
- .copy-section {
- h1 {
- font-size: 74px;
- padding-top: 0;
- line-height: 4.15rem;
- }
- h2 {
- font-size: 32px;
- font-weight: 400;
- margin-bottom: 1rem;
- }
- h3 {
- font-size: 28px;
- font-weight: 400;
- margin-bottom: 1rem;
- }
- p {
- font-size: 18px;
- padding-right: 2rem;
- }
- @media screen and (max-width: $media-lg) {
- h1 {
- font-size: 52px;
- padding-top: 0;
- line-height: 3rem;
- }
- h2 {
- font-size: 20px;
- font-weight: 400;
- margin-bottom: 0.5rem;
- }
- h3 {
- font-size: 20px;
- font-weight: 400;
- margin-bottom: 0.5rem;
- }
- p {
- font-size: 16px;
- padding-right: 2rem;
- }
- }
- }
-
- z-index: 990;
- padding-top: 5rem;
- position: fixed;
- top: 0;
- width: 100%;
- height: 100%;
- background-color: #000000;
- overflow-y: scroll !important;
- -webkit-overflow-scrolling: touch;
-
- .container {
- display: block;
- position: relative;
- padding-bottom: 10rem;
- }
-
- .search-row {
- width: 100%;
- @media screen and (max-width: $media-md) {
- input {
- font-size: 16px;
- }
- }
- position: -webkit-sticky;
- top: -5rem;
- z-index: 9999;
- padding-top: 1rem;
- padding-bottom: 0.5rem;
- background-color: #000000;
-
- form {
- margin-top: 0;
- padding-top: 0;
- }
- }
- .btn {
- margin-right: 2rem;
- transition: all 0.325s ease-in-out;
- margin-bottom: 1rem;
- }
- .search-modal-container {
- .modal-copy-row {
- h1,
- h2,
- h3,
- h4,
- h5,
- p {
- transition: all 350ms ease;
- color: #666666 !important;
- }
- }
- .activesec {
- h1,
- h2,
- h3,
- h4,
- h5,
- p {
- transition: all 350ms ease;
-
- color: #ffffff !important;
- }
- }
- }
- .modal-copy-row {
- padding-bottom: 4rem;
- }
-
- .main-page__container {
- width: 100%;
- max-width: 100%;
- font-size: 20px;
- font-weight: 400;
- letter-spacing: 0.05rem;
- .search-button > .search-button__btn {
- padding-left: 2rem;
- padding-right: 2rem;
- margin-right: 0;
- font-size: 20px;
- font-weight: 400;
- letter-spacing: 0.05rem;
- height: 3rem;
- @media screen and (max-width: $media-md) {
- margin-left: 0.25rem;
- padding-left: 0.25rem;
- padding-right: 0.25rem;
- }
- }
- }
- .form-control {
- height: 3rem;
- font-size: 20px;
- font-weight: 400;
- letter-spacing: 0.05rem;
-
- // Fake Focus
- color: var(--input-color);
- background-color: var(--input-bg);
- border-color: #1c7ed6;
- outline: 0;
- box-shadow: 0 0 0.125rem 0.125rem rgba(28, 126, 214, 0.25);
- }
- .active {
- box-shadow: rgba(69, 127, 183, 0.7) 0 0 0.16rem 0.125rem;
- }
-
- .intelligence-row {
- padding-top: 4rem;
- }
-
- .hover-overlay__actions,
- .hover-overlay__action {
- .btn {
- margin: 0;
- }
- }
- .action-row {
- justify-content: center;
- font-size: 18px;
- margin-top: 4rem;
- .action-col {
- padding-bottom: 2rem;
- a {
- color: #1c7ed6;
- }
- p {
- margin-bottom: 0.5rem;
- }
- }
- }
- }
- .modal-integrations {
- .btn-integrations {
- display: inline-flex;
- align-items: center;
- font-size: 20px;
- font-weight: 400;
- .logo-icon {
- height: 1.5rem;
- width: 1.5rem;
- display: inline-block;
- margin-right: 0.5rem;
- background-size: contain;
- background-repeat: no-repeat;
- }
- }
- .btn-github {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/github.png);
- }
- }
- .btn-gitlab {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/gitlab.svg);
- }
- }
- .btn-phabricator {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/phabricator.png);
- }
- }
- .btn-chrome {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/chrome.svg);
- }
- }
- .btn-firefox {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/firefox.svg);
- }
- }
- .btn-atom {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/atom.svg);
- }
- }
- .btn-intellij {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/jetbrains.svg);
- }
- }
- .btn-vscode {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/vscode.svg);
- }
- }
- .btn-sublime {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/sublime.svg);
- }
- }
- .btn-vim {
- .logo-icon {
- background-image: url(https://about.sourcegraph.com/integrations/vim.svg);
- }
- }
- }
- .modal-close {
- display: none;
- opacity: 0;
- }
- .modal-open {
- z-index: 990;
- // Animations
- animation: display 350ms ease-in 0s;
- @keyframes display {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
- }
-
- .modal-header {
- opacity: 0;
- animation: display 350ms ease-in 250ms forwards;
- @keyframes display {
- from {
- opacity: 0;
- transform: translateY(1.25rem);
- }
- to {
- opacity: 1;
- transform: translateY(1.25rem);
- }
- }
- }
- .search-row-animate {
- animation: display 350ms ease-in 400ms forwards;
- @keyframes display {
- from {
- opacity: 0;
- transform: translateY(1.25rem);
- }
- to {
- opacity: 1;
- transform: translateY(0);
- }
- }
- opacity: 1;
- }
- @for $i from 1 through 8 {
- .modal-copy-row:nth-child(#{$i}) {
- $hold-time: (150 * $i) + 300;
- opacity: 0;
- animation: display 350ms ease-in-out #{$hold-time}ms forwards;
- @keyframes display {
- from {
- opacity: 0;
- transform: translateY(1.25rem);
- }
- to {
- opacity: 1;
- transform: translateY(0);
- }
- }
- }
- }
- // End Animations
- }
- .modal-closing {
- animation: closeModal 350ms ease-in 0s forwards;
- @keyframes closeModal {
- from {
- opacity: 1;
- }
- to {
- opacity: 0;
- }
- }
- }
-
- .query-input2__suggestions {
- z-index: 999;
- }
- .code-intellify-container,
- .code-intellify-container-modal {
- background-color: #10111a;
- .code-header {
- width: 100%;
- background-color: #232532;
- border-top-left-radius: 0.5rem;
- border-top-right-radius: 0.5rem;
- padding-left: 0.5rem;
- padding-right: 0.5rem;
- padding-bottom: 0.25rem;
- padding-top: 0.25rem;
- &__title,
- &__link {
- font-family: SFMono-Regular, SF Mono, Consolas, Menlo, DejaVu Sans Mono, monospace;
- font-size: 12px;
- }
- &__link {
- float: right;
- padding-top: 0.25rem;
- a {
- color: #329af0;
- }
- }
- }
- }
- .footer-section {
- // Designers Note: Most of the footer is pixel-aligned to match about.sourcegraph.com.
-
- // Redefine a REM to match about.sourcegraph.com
- font-size: 16px;
- //
-
- position: sticky;
- position: -webkit-sticky;
- z-index: 4;
- background: #151c28;
- color: #7a8fb8;
- padding: 4rem 0 1rem 0;
- overflow: hidden !important;
-
- .small__contact {
- padding-top: 1.5rem;
- margin-bottom: -2rem;
- @media screen and (min-width: $media-md) {
- display: none;
- }
- }
- .logo__section {
- a {
- color: $light-6;
- }
- .footer__logo {
- padding: 0 0 1.25rem 0;
- margin: 0 0 0 -0.5rem;
- }
- @media screen and (max-width: $media-md) {
- padding-bottom: 0.2rem;
- margin-top: -2.5rem;
-
- .footer__contact {
- display: none;
- }
- }
- }
-
- .footer__extend {
- transition: all 0.3s ease-in-out;
- * {
- transition: all 0.3s ease-in-out;
- }
- h3 {
- cursor: pointer;
- }
- ul {
- overflow: hidden !important;
- padding-left: 0;
- li {
- @media screen and (max-width: $media-md) {
- transition: all 0.3s ease-in-out;
- position: relative;
- top: -60px;
- overflow: hidden !important;
- }
- }
- }
- @media screen and (min-width: $media-md) {
- input,
- .close--icon {
- display: none;
- }
- }
- @media screen and (max-width: $media-md) {
- &:last-of-type {
- border-bottom: solid 1px $light-2;
- }
- padding-top: 0.5rem;
- border-top: solid 1px $light-2;
- &.community,
- &.company,
- &.features,
- &.resources {
- .close--icon {
- height: 1.125rem;
- width: 1.125rem;
- position: absolute;
- top: calc(1rem - 10px);
- right: 1rem;
- transition: all 0.3s ease-in-out;
-
- svg {
- height: 1.125rem;
- width: 1.125rem;
- transition: transform 0.3s ease-in-out;
- transform: rotate(-45deg);
- }
- svg path {
- fill: $light-2;
- }
- }
- li:last-child {
- padding-bottom: 0.5rem;
- }
- input {
- width: 100%;
- height: 2rem;
- position: absolute;
- top: 0;
- opacity: 0;
- cursor: pointer;
- z-index: 9999;
- // stylelint-disable-next-line scss/selector-no-redundant-nesting-selector
- & + ul {
- display: hidden;
- height: 0;
- padding: 0;
- }
- &:checked + ul {
- display: block;
- height: 100%;
- }
- &:checked + ul li {
- transition: all 0.3s ease-in-out;
- display: block;
- top: 0;
- }
- &:checked ~ .close--icon {
- svg {
- transition: transform 0.3s ease-in-out;
- transform: rotate(0deg);
- }
- }
- }
- }
- }
- }
-
- .social__column {
- .icon {
- margin-left: 1rem;
- svg path {
- fill: $dark-1;
- }
- &:hover {
- svg path {
- fill: $dark-11;
- }
- }
- }
- img,
- .btn {
- margin-bottom: 1rem;
- }
- .copyright {
- color: $dark-1;
- }
- }
- h3 {
- text-transform: uppercase;
- font-weight: 400;
- font-size: 16px;
- letter-spacing: 0.1rem;
- }
- ul {
- color: $light-6;
- margin: 0;
- list-style: none;
-
- li {
- margin-bottom: 0.5rem;
-
- a {
- color: $light-6;
- &:hover {
- color: $light-11;
- text-decoration: underline;
- }
- }
- }
- }
- .copyright__container {
- margin: 3rem 0 0 0;
- padding-top: 1rem;
- border-top: 2px solid $dark-4;
- .copyright {
- float: left;
- @media screen and (max-width: $media-md) {
- float: none;
- }
- }
- .terms {
- float: right;
- a {
- margin-left: 2rem;
- }
- @media screen and (max-width: $media-md) {
- float: none;
- a:first-of-type {
- margin-left: 0;
- }
- }
- }
- }
- }
- .align-footer {
- align-content: flex-end !important;
-
- @media screen and (max-width: $media-lg) {
- padding-top: 2rem;
- }
-
- * {
- align-self: center;
- }
- }
-}
-.small-hidden {
- @media screen and (max-width: $media-lg) {
- display: none !important;
- }
-}
-
-.theme-light {
- .main-page {
- &__sign-in {
- color: $color-light-text-4;
- }
- }
-}
diff --git a/web/src/search/input/MainPage.tsx b/web/src/search/input/MainPage.tsx
deleted file mode 100644
index cc78c88fccf..00000000000
--- a/web/src/search/input/MainPage.tsx
+++ /dev/null
@@ -1,1037 +0,0 @@
-import * as H from 'history'
-import ChevronRightIcon from 'mdi-react/ChevronRightIcon'
-import CloseIcon from 'mdi-react/CloseIcon'
-import MapSearchIcon from 'mdi-react/MapSearchIcon'
-import * as React from 'react'
-import { parseSearchURLQuery } from '..'
-import { ExtensionsControllerProps } from '../../../../shared/src/extensions/controller'
-import * as GQL from '../../../../shared/src/graphql/schema'
-import { PlatformContextProps } from '../../../../shared/src/platform/context'
-import { Form } from '../../components/Form'
-import { HeroPage } from '../../components/HeroPage'
-import { PageTitle } from '../../components/PageTitle'
-import { eventLogger } from '../../tracking/eventLogger'
-import { limitString } from '../../util'
-import { queryIndexOfScope, submitSearch } from '../helpers'
-import { CodeIntellifyBlob } from './CodeIntellifyBlob'
-import { QueryInputForModal } from './QueryInputForModal'
-import { SearchButton } from './SearchButton'
-
-interface Props extends ExtensionsControllerProps, PlatformContextProps {
- authenticatedUser: GQL.IUser | null
- location: H.Location
- history: H.History
- isLightTheme: boolean
- onThemeChange: () => void
- onMainPage: (mainPage: boolean) => void
-}
-
-interface State {
- /** The query value entered by the user in the query input */
- userQuery: string
- // modalXXopen sets a state that the modal is open before animations or closed after animation
- // modalXXclosing sets a state that starts the closing process
- modalSearchOpen: boolean
- modalIntelligenceOpen: boolean
- modalSearchClosing: boolean
- modalIntelligenceClosing: boolean
- modalIntegrationsOpen: boolean
- modalIntegrationsClosing: boolean
- // determine what button in modal is active
- activeButton?: string
- // determine what section inside a modal is active
- activesection?: string
- // animateModalXX starts the animation process after opening.
- animateModalSearch: boolean
- animateModalIntelligence: boolean
- animateModalIntegrations: boolean
- // Manual click state is to determine if animation should be stopped
- manualClick?: boolean
- bgScrollStyle: string
-}
-const heroEyebrow = 'Sourcegraph'
-const heroTitle = 'Search, navigate, and review code. Find answers.'
-const heroCopyTop =
- 'Sourcegraph is a free, open-source, self-hosted code search and navigation tool for developers. Use it with any Git code host for teams of any size.'
-const heroCopyBottom = 'Upgraded features available for enterprise users.'
-
-const searchSections = [
- {
- title: 'Powerful, flexible queries',
- paragraph:
- 'Sourcegraph code search performs full-text searches and supports both regular expression and exact queries. By default, Sourcegraph searches across all your repositories. Our search query syntax allows for advanced queries, such as searching over any branch or commit, narrowing searches by programming language or file pattern, and more.',
- buttons: [
- { query: 'repo:^gitlab.com/ ', text: 'Code on GitLab' },
- { query: 'repogroup:goteam file:\\.go$', text: 'Go Code by Go Team' },
- {
- query: 'repogroup:ethereum file:\\.(txt|md)$ file:(test|spec) ',
- text: 'Core Ethereum test files',
- },
- { query: 'repogroup:angular file:\\.JSON$', text: 'Angular JSON Files' },
- ],
- },
- {
- title: 'Commit diff search',
- paragraph:
- 'Search over commit diffs using type:diff to see how your codebase has changed over time. This is often used to find changes to particular functions, classes, or areas of the codebase when debugging. You can also search within commit diffs on multiple branches by specifying the branches in a repo: field after the @ sign.',
- buttons: [
- { query: 'repo:^github\\.com/apple/swift$@master-next type:diff', text: 'Swift diff' },
- { query: 'repo:^github.com/facebook/react$ file:(test|spec) type:diff', text: 'React test file diff' },
- {
- query: 'repo:^github.com/golang/oauth2$ type:diff',
- text: 'Go oauth2 diff',
- },
- {
- query: 'repo:^github.com/kubernetes/kubernetes$ type:diff statefulset',
- text: 'Kubernetes statefulset diff',
- },
- ],
- },
- {
- title: 'Commit message search',
- paragraph:
- 'Searching over commit messages is supported in Sourcegraph by adding type:commit to your search query. Separately, you can also use the message:"any string" token to filter type:diff searches for a given commit message.',
- buttons: [
- { query: 'type:commit repogroup:angular author:google.com>$ ', text: 'Angular commits by Googlers' },
- { query: 'repogroup:npm type:commit security', text: 'NPM commits mentioning security' },
- {
- query: 'repogroup:ethereum type:commit money loss',
- text: "Ethereum commits mentioning 'money loss'",
- },
- { query: 'repo:^github.com/sourcegraph/sourcegraph type:commit', text: 'Sourcegraph commits' },
- ],
- },
- {
- title: 'Symbol Search',
- paragraph:
- 'Searching for symbols makes it easier to find specific functions, variables and more. Use the type:symbol filter to search for symbol results. Symbol results also appear in typeahead suggestions, so you can jump directly to symbols by name.',
- buttons: [
- { query: 'repogroup:goteam type:symbol httpRouter', text: 'Go code with httpRouter' },
- { query: 'repo:^github.com/apple/swift$ type:symbol main', text: "Calls to 'main' in Swift" },
- {
- query: 'repo:golang/go$ type:symbol sprintf',
- text: 'Go sprintf',
- },
- { query: 'repo:golang/go$ type:symbol newDecoder', text: 'Go newDecoder' },
- ],
- },
-]
-const intelligenceSections = [
- {
- title: 'Code browsing',
- paragraph:
- 'View open source code, like gorilla/mux, on sourcegraph.com, or deploy your own instance to see public code alongside your private code. See how your codebase changes over time in by browsing through branches, commits, and diffs.',
- },
- {
- title: 'Advanced code intelligence',
- paragraph:
- 'Code intelligence makes browsing code easier, with IDE-like hovers, go-to-definition, and find-references on your code, powered by language servers based on the open-source Language Server Protocol.',
- },
- {
- title: 'Hover tooltip',
- paragraph:
- 'Use the hover tooltip to discover and understand your code faster. Click on a token and then go to its definition, other references, or implementations. Speed through reviews by understanding new code, changed code, and what it affects.',
- },
- {
- title: '',
- paragraph:
- 'Code intelligence is powered by language servers based on the open-standard Language Server Protocol (published by Microsoft, with participation from Facebook, Google, Sourcegraph, GitHub, RedHat, Twitter, Salesforce, Eclipse, and others). Visit langserver.org to learn more about the Language Server Protocol, find the latest support for your favorite language, and get involved.',
- },
-]
-
-const integrationsSections = [
- {
- title: 'Connect across your development workflow.',
- paragraph:
- 'Sourcegraph has powerful integrations for every step of development. From planning with code discussion, development with Sourcegraph and IDE extensions, to review in PRs and Issues. Use Sourcegraph integrations to get code intelligence at every step of your workflow.',
- buttons: [],
- },
- {
- title: 'Browser extensions',
- paragraph:
- 'Code intelligence makes browsing code easier, with IDE-like hovers, go-to-definition, and find-references on your code, powered by language servers based on the open-source Language Server Protocol.',
- buttons: [
- {
- id: 'btn-chrome',
- text: 'Chrome',
- link: 'https://chrome.google.com/webstore/detail/sourcegraph/dgjhfomjieaadpoljlnidmbgkdffpack',
- },
- ],
- },
-
- {
- title: 'Code host integrations',
- paragraph:
- 'The Sourcegraph browser extension will add go-to-definition, find-references, hover tooltips, and code search to all files and diffs on supported code hosts. The extension will also add code intelligence and code search to public repositories. ',
- buttons: [
- { id: 'btn-gitlab', text: 'GitLab', link: 'https://docs.sourcegraph.com/integration/browser_extension' },
- { id: 'btn-github', text: 'GitHub', link: 'https://docs.sourcegraph.com/integration/browser_extension' },
- {
- id: 'btn-phabricator',
- text: 'Phabricator',
- link: 'https://docs.sourcegraph.com/integration/browser_extension',
- },
- ],
- },
- {
- title: 'Editor extensions',
- paragraph:
- 'Our editor plugins let you quickly jump to files and search code on your Sourcegraph instance from your editor. Seamlessly jump for development to review without missing a step.',
- buttons: [
- { id: 'btn-atom', text: 'Atom', link: 'https://atom.io/packages/sourcegraph' },
- { id: 'btn-intellij', text: 'IntelliJ', link: 'https://plugins.jetbrains.com/plugin/9682-sourcegraph' },
- {
- id: 'btn-sublime',
- text: 'Sublime',
- link: 'https://github.com/sourcegraph/sourcegraph-sublime',
- },
- {
- id: 'btn-vscode',
- text: 'Visual Studio Code',
- link: 'https://marketplace.visualstudio.com/items?itemName=sourcegraph.sourcegraph',
- },
- ],
- },
-]
-
-const inlineStyle = `
- .layout {
- display: block !important;
- }
- * {
- overflow: visible !important;
- }
- .hero-tooltip {
- z-index: 1;
- position: fixed !important;
- transform: translateY(44px);
- }
- .hover-overlay__contents {
- overflow-y: auto !important;
- max-height: 200px;
- }
- .modal-tooltip {
- z-index: 9999 !important;
- opacity: 1 !important;
- visbility: visbily !important;
- }
-`
-// Set the defauly hover token of the hero tooltip
-const defaultTooltipHeroPosition = { line: 244, character: 11 }
-
-// Set the defauly hover token of the hero tooltip
-const defaultTooltipModalPosition = { line: 248, character: 11 }
-
-/**
- * The main page
- */
-export class MainPage extends React.Component {
- private static HIDE_REPOGROUP_SAMPLE_STORAGE_KEY = 'MainPage/hideRepogroupSample'
-
- private overlayPortal: HTMLElement | undefined
-
- constructor(props: Props) {
- super(props)
-
- const query = parseSearchURLQuery(props.location.search)
-
- this.state = {
- userQuery: query || '',
- modalSearchOpen: false,
- modalSearchClosing: false,
- modalIntelligenceOpen: false,
- modalIntelligenceClosing: false,
- modalIntegrationsOpen: false,
- modalIntegrationsClosing: false,
- manualClick: false,
- activesection: 'none',
- animateModalSearch: false,
- animateModalIntelligence: false,
- animateModalIntegrations: false,
- bgScrollStyle: `
- .feature-card {
- transform: translateY(-0px);
- opacity: .5;
- }
- .global-alerts {
- position: sticky;
- position: -webkit-sticky;
- z-index: 99;
- }
- `,
- }
- }
-
- public componentDidMount(): void {
- eventLogger.logViewEvent('Home')
- if (
- window.context.sourcegraphDotComMode &&
- !localStorage.getItem(MainPage.HIDE_REPOGROUP_SAMPLE_STORAGE_KEY) &&
- !this.state.userQuery
- ) {
- this.setState({ userQuery: 'repogroup:sample' })
- }
-
- const portal = document.createElement('div')
- document.body.appendChild(portal)
- this.overlayPortal = portal
-
- // communicate onMainPage to SourcegraphWebApp for dark theme look
- if (window.context.sourcegraphDotComMode) {
- this.props.onMainPage(true)
- }
-
- // Add class to body to prevent global element styles from affecting other pages
- const windowBody = document.body
- windowBody.classList.add('main-page')
- }
-
- public componentWillUnmount(): void {
- this.props.onMainPage(false)
- const windowBody = document.body
- windowBody.classList.remove('main-page')
- windowBody.classList.remove('modal-open')
- }
- public render(): JSX.Element | null {
- if (!window.context.sourcegraphDotComMode) {
- return
- }
- return (
-
-
-
-
-
-
-
-
-
-
-
-
Powering developers at
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Advanced code search
-
Find. Then replace.
-
- Search in files and diffs on your private code using simple terms, regular
- expressions, and other filters.
-
-
- Syncs repositories with your code host and supports searching any commit/branch,
- with no indexing delay.
-
-
- Explore code search
-
-
-
-
-
-
-
-
-
-
Enhanced code browsing and intelligence
-
Mine your language.
-
- Solve problems before they exist, commit by commit. Code intelligence makes
- browsing code easier, with IDE-like hovers, go-to-definition, and
- find-references on your code, powered by Sourcegraph extensions and language
- servers based on the open-source Language Server Protocol.
-
-
- It even works in code review diffs on GitHub and GitLab with our browser
- extensions.
-
-
- Explore code intelligence
-
-
-
-
-
-
-
-
-
-
Integrations
-
Get it. Together.
-
- Connect your Sourcegraph instance with your existing tools. Get code
- intelligence while browsing code on the web, and code search from your editor.
-
-
- Explore integrations
-
-
-
-
-
-
-
-
-
-
-
Deploy Sourcegraph
-
Free. For all.
-
- The pace at which humans can write code is the only thing that stands between us and
- flying cars, a habitat on Mars, and a cure for cancer. That's why developers can get
- started and deploy Sourcegraph for free, and contribute to our code on GitHub.
-
-
- Deploy Sourcegraph
-
-
- Sourcegraph on GitHub
-
-
-
-
Sourcegraph pricing
-
Size. Up.
-
- When you grow to hundreds or thousands of users and repositories, scale up
- instantly, and protect your uptime with Sourcegraph on Kubernetes, external backups,
- and custom support agreements. Start with Sourcegraph core for free and scale with
- your deployment.
-
-
- Sourcegraph pricing
-
-
-
-
-
-
-
-
-
-
Open. For business.
-
Sourcegraph is open source.
-
- We opened up Sourcegraph to bring code search and intelligence to more developers
- and developer ecosystems—and to help us realize the{' '}
- Sourcegraph master plan . We're also
- excited about what this means for Sourcegraph as a company. All of our customers,
- many with hundreds or thousands of developers using Sourcegraph internally every
- day, started out with a single developer spinning up a Sourcegraph instance and
- sharing it with their team. Being open-source makes it even easier to use
- Sourcegraph.
-
-
- Release announcement
-
-
- Sourcegraph on GitHub
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright © 2018 Sourcegraph, Inc.
-
-
- Terms
- Privacy
-
-
-
-
-
-
-
-
-
-
-
-
-
Advanced code search
- Find. Then replace.
-
-
-
-
- {searchSections.map(({ title, paragraph, buttons }, i) => (
-
-
-
{title}
-
{paragraph}
- {buttons.map(({ text, query }, j) => (
-
- {text}
-
- ))}
-
-
- ))}
-
-
-
- Get started with Sourcegraph for free, and get get cross-repository code
- intelligence, advanced code search, and extensive integrations.
-
-
-
- Deploy Sourcegraph
-
-
-
-
-
- Explore the power and extensibility of Sourcegraph's search query syntax, and learn
- how to search across all of your public and private code.
-
-
- Search documentation
-
-
-
-
-
- Close
-
-
-
-
-
-
-
-
-
-
-
Enhanced code browsing and intelligence
- Mine your language.
-
-
-
-
- {intelligenceSections.map(({ title, paragraph }, i) => (
-
-
-
{title}
-
{paragraph}
-
-
- ))}
-
-
-
-
-
-
-
-
- Get started with Sourcegraph for free, and get get cross-repository code
- intelligence, advanced code search, and extensive integrations.
-
-
-
- Deploy Sourcegraph
-
-
-
-
-
- Explore how Sourcegraph's code intelligence can augment and add to your workflow,
- prepare you for code review, and speed through development.
-
-
- Code intelligence documentation
-
-
-
-
-
- Close
-
-
-
-
-
-
-
-
-
-
-
Integrations
- Get it. Together.
-
-
-
-
- {integrationsSections.map(({ title, paragraph, buttons }, i) => (
-
-
-
{title}
-
{paragraph}
- {buttons.map(({ text, id, link }, j) => (
-
-
- {text}
-
- ))}
-
-
- ))}
-
-
-
-
-
-
- Get started with Sourcegraph for free, and get get cross-repository code
- intelligence, advanced code search, and extensive integrations.
-
-
-
- Deploy Sourcegraph
-
-
-
-
-
- Explore all of Sourcegraph's integrations and see how you can get cross-repository
- code intelligence on your favorite code host and editor.
-
-
- Integrations documentation
-
-
-
-
-
-
- Close
-
-
-
-
- )
- }
-
- private handleQueryChange = (activeButton: string, passedQ: string) => () => {
- if (passedQ === '') {
- this.setState({ activeButton, manualClick: true, activesection: '99' })
- } else {
- this.setState({ activeButton, userQuery: passedQ, manualClick: true, activesection: '99' })
- }
- }
-
- private activateModal = (section: string) => () => {
- const windowBody = document.body
- windowBody.classList.add('modal-open')
-
- if (section === 'intelligence') {
- this.setState(state => ({ modalIntelligenceOpen: !state.modalIntelligenceOpen }))
- this.setState(state => ({ animateModalIntelligence: !state.animateModalIntelligence }))
- this.setState(state => ({ activesection: '99' }))
- } else if (section === 'integrations') {
- this.setState(state => ({ modalIntegrationsOpen: !state.modalIntegrationsOpen }))
- this.setState(state => ({ animateModalIntegrations: !state.animateModalIntegrations }))
- this.setState(state => ({ activesection: '99' }))
- } else if (section === 'search') {
- this.setState(state => ({ modalSearchOpen: !state.modalSearchOpen }))
- this.setState(state => ({ animateModalSearch: !state.modalSearchOpen }))
- setTimeout(() => {
- if (this.state.animateModalSearch) {
- this.setState(state => ({ animateModalSearch: false }))
- }
- }, 750)
- setTimeout(() => {
- if (this.state.manualClick === false) {
- this.setState(state => ({
- activeButton: '0-1',
- activesection: '0',
- userQuery: 'repogroup:goteam file:\\.go$',
- }))
- }
- }, 1450)
- setTimeout(() => {
- if (this.state.manualClick === false) {
- this.setState(state => ({
- activeButton: '1-0',
- activesection: '1',
-
- userQuery: 'repo:^github\\.com/apple/swift$@master-next type:diff',
- }))
- }
- }, 7450)
- setTimeout(() => {
- if (this.state.manualClick === false) {
- this.setState(state => ({
- activeButton: '2-3',
- activesection: '2',
- userQuery: 'repogroup:goteam file:\\.go$',
- }))
- }
- }, 15550)
- setTimeout(() => {
- if (this.state.manualClick === false) {
- this.setState(state => ({
- activeButton: '3-2',
- activesection: '3',
- userQuery: 'repogroup:goteam file:\\.go$',
- }))
- }
- }, 21450)
- setTimeout(() => {
- if (this.state.manualClick === false) {
- this.setState(state => ({
- activeButton: '0-0',
- activesection: '99',
- userQuery: 'repogroup:goteam file:\\.go$',
- }))
- }
- }, 28450)
- }
- }
-
- private closeModal = (modalName: string) => () => {
- const windowBody = document.body
- windowBody.classList.remove('modal-open')
-
- if (modalName === 'search') {
- this.setState(state => ({ modalSearchClosing: !state.modalSearchClosing, animateModalSearch: false }))
- // RESET DID CLOSE
- setTimeout(() => {
- this.setState(state => ({ modalSearchOpen: !state.modalSearchOpen }))
- this.setState(state => ({ modalSearchClosing: !state.modalSearchClosing }))
- }, 400)
- } else if (modalName === 'intelligence') {
- this.setState(state => ({
- modalIntelligenceClosing: !state.modalIntelligenceClosing,
- animateModalIntelligence: false,
- }))
- // RESET DID CLOSE
- setTimeout(() => {
- this.setState(state => ({
- modalIntelligenceOpen: !state.modalIntelligenceOpen,
- modalIntelligenceClosing: !state.modalIntelligenceClosing,
- }))
- }, 400)
- } else if (modalName === 'integrations') {
- this.setState(state => ({
- modalIntegrationsClosing: !state.modalIntegrationsClosing,
- animateModalIntegrations: false,
- }))
- // RESET DID CLOSE
- setTimeout(() => {
- this.setState(state => ({
- modalIntegrationsOpen: !state.modalIntegrationsOpen,
- modalIntegrationsClosing: !state.modalIntegrationsClosing,
- }))
- }, 400)
- }
- }
-
- private onUserQueryChange = (userQuery: string) => {
- this.setState({ userQuery })
-
- if (window.context.sourcegraphDotComMode) {
- if (queryIndexOfScope(userQuery, 'repogroup:sample') !== -1) {
- localStorage.removeItem(MainPage.HIDE_REPOGROUP_SAMPLE_STORAGE_KEY)
- } else {
- localStorage.setItem(MainPage.HIDE_REPOGROUP_SAMPLE_STORAGE_KEY, 'true')
- }
- }
- }
-
- private onSubmit = (event: React.FormEvent): void => {
- event.preventDefault()
- submitSearch(this.props.history, this.state.userQuery, 'home')
- }
-
- private getPageTitle(): string | undefined {
- const query = parseSearchURLQuery(this.props.location.search)
- if (query) {
- return `${limitString(this.state.userQuery, 25, true)}`
- }
- return undefined
- }
-}
diff --git a/web/src/search/input/QueryInputForModal.scss b/web/src/search/input/QueryInputForModal.scss
deleted file mode 100644
index 8fe5e3d9f14..00000000000
--- a/web/src/search/input/QueryInputForModal.scss
+++ /dev/null
@@ -1,76 +0,0 @@
-@import './Suggestion';
-
-.query-input2-for-modal {
- width: 100%;
- position: relative;
-
- &__input {
- // Right side is flush with SearchButton.
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- }
-
- &__suggestions {
- position: absolute;
- width: 100%;
- z-index: 1;
- max-height: 25rem;
- margin: 0;
- overflow-x: hidden;
- overflow-y: auto;
- overflow-y: overlay;
- background-color: #000000;
- border: solid 1px #1b548a;
- border-top: none;
- padding: 0;
-
- .theme-light & {
- background-color: $color-light-bg-2;
- border-top: none;
- }
-
- // Custom scrollbar
- &::-webkit-scrollbar {
- width: 0.5rem;
- height: 0.5rem;
- }
-
- &::-webkit-scrollbar-corner,
- &::-webkit-scrollbar-track {
- background-color: transparent;
- }
-
- &::-webkit-scrollbar-thumb {
- background-color: #2a3a51;
- }
-
- .theme-light &::-webkit-scrollbar-thumb {
- background-color: $color-light-bg-3;
- }
-
- * {
- display: inline-block;
- }
- li {
- display: block;
- position: relative;
- }
- }
-
- &__loading-notifier {
- position: absolute;
- z-index: 1;
- right: 0.5rem;
- padding-left: 0.25rem;
- bottom: 0.375rem;
- background-color: $color-bg-4;
- }
-}
-
-.theme-light {
- .query-input2 {
- &__loading-notifier {
- background-color: $color-light-bg-1;
- }
- }
-}
diff --git a/web/src/search/input/QueryInputForModal.tsx b/web/src/search/input/QueryInputForModal.tsx
deleted file mode 100644
index fecb598686e..00000000000
--- a/web/src/search/input/QueryInputForModal.tsx
+++ /dev/null
@@ -1,425 +0,0 @@
-import { LoadingSpinner } from '@sourcegraph/react-loading-spinner'
-import * as H from 'history'
-import * as React from 'react'
-import { fromEvent, merge, Observable, of, Subject, Subscription } from 'rxjs'
-import {
- catchError,
- debounceTime,
- delay,
- distinctUntilChanged,
- filter,
- map,
- publishReplay,
- refCount,
- repeat,
- startWith,
- switchMap,
- takeUntil,
- tap,
- toArray,
-} from 'rxjs/operators'
-import { Key } from 'ts-key-enum'
-import { eventLogger } from '../../tracking/eventLogger'
-import { scrollIntoView } from '../../util'
-import { fetchSuggestions } from '../backend'
-import { createSuggestion, Suggestion, SuggestionItem } from './Suggestion'
-
-/**
- * The query input field is clobbered and updated to contain this subject's values, as
- * they are received. This is used to trigger an update; the source of truth is still the URL.
- *
- * This file is mostly the same as Queryinput.tsx but differs for the use on the homepage on line
- * 326-335. It also does not need onInputFocus function.
- *
- */
-export const queryUpdates = new Subject()
-
-interface Props {
- location: H.Location
- history: H.History
-
- /** The value of the query input */
- value: string
-
- /** Called when the value changes */
- onChange: (newValue: string) => void
-
- /**
- * A string that is appended to the query input's query before
- * fetching suggestions.
- */
- prependQueryForSuggestions?: string
-
- /** Whether the input should be autofocused (and the behavior thereof) */
- autoFocus?: true | 'cursor-at-end'
-
- /** The input placeholder, if different from the default is desired. */
- placeholder?: string
-
- /**
- * Whether this input should behave like the global query input: (1)
- * pressing the '/' key focuses it and (2) other components contribute a
- * query to it with their context (such as the repository area contributing
- * 'repo:foo@bar' for the current repository and revision).
- *
- * At most one query input per page should have this behavior.
- */
- hasGlobalQueryBehavior?: boolean
-}
-
-interface State {
- /** Whether the query input is focused */
- inputFocused: boolean
-
- /** Whether suggestions are shown or not */
- hideSuggestions: boolean
-
- /** The suggestions shown to the user */
- suggestions: Suggestion[]
-
- /** Index of the currently selected suggestion (-1 if none selected) */
- selectedSuggestion: number
-
- /** Whether suggestions are currently being fetched */
- loading: boolean
-}
-
-export class QueryInputForModal extends React.Component {
- private static SUGGESTIONS_QUERY_MIN_LENGTH = 2
-
- private componentUpdates = new Subject()
-
- /** Subscriptions to unsubscribe from on component unmount */
- private subscriptions = new Subscription()
-
- /** Emits on keydown events in the input field */
- private inputKeyDowns = new Subject>()
-
- /** Emits new input values */
- private inputValues = new Subject()
-
- /** Emits when the input field is clicked */
- private inputFocuses = new Subject()
-
- /** Emits when the suggestions are hidden */
- private suggestionsHidden = new Subject()
-
- /** Only used for selection and focus management */
- private inputElement?: HTMLInputElement
-
- /** Only used for scroll state management */
- private suggestionListElement?: HTMLElement
-
- /** Only used for scroll state management */
- private selectedSuggestionElement?: HTMLElement
-
- /** Only used to keep track if the user has typed a single character into the input field so we can log an event once. */
- private hasLoggedFirstInput = false
-
- constructor(props: Props) {
- super(props)
-
- this.state = {
- hideSuggestions: false,
- inputFocused: false,
- loading: false,
- selectedSuggestion: -1,
- suggestions: [],
- }
-
- this.subscriptions.add(
- // Trigger new suggestions every time the input field is typed into
- this.inputValues
- .pipe(
- tap(query => this.props.onChange(query)),
- distinctUntilChanged(),
- debounceTime(200),
- switchMap(query => {
- if (query.length < QueryInputForModal.SUGGESTIONS_QUERY_MIN_LENGTH) {
- return [{ suggestions: [], selectedSuggestion: -1, loading: false }]
- }
- const fullQuery = [this.props.prependQueryForSuggestions, this.props.value]
- .filter(s => !!s)
- .join(' ')
- const suggestionsFetch = fetchSuggestions(fullQuery).pipe(
- map(createSuggestion),
- toArray(),
- map((suggestions: Suggestion[]) => ({
- suggestions,
- selectedSuggestion: -1,
- hideSuggestions: false,
- loading: false,
- })),
- catchError((err: Error) => {
- console.error(err)
- this.setState({ loading: false })
- // HACK: if we catchError before 100ms, then the loader will display over us.
- // This is not a good fix.
- setTimeout(() => this.setState({ loading: false }), 120)
- return [{}]
- }),
- publishReplay(),
- refCount()
- )
- return merge(
- suggestionsFetch,
- // Show a loader if the fetch takes longer than 100ms
- of({ loading: true }).pipe(
- delay(100),
- takeUntil(suggestionsFetch)
- )
- )
- }),
- // Abort suggestion display on route change or suggestion hiding
- takeUntil(this.suggestionsHidden),
- // But resubscribe afterwards
- repeat()
- )
- .subscribe(
- state => {
- this.setState(state as State)
- },
- err => {
- this.setState({ loading: false })
- console.error(err)
- }
- )
- )
-
- if (this.props.hasGlobalQueryBehavior) {
- // Quick-Open hotkeys
- this.subscriptions.add(
- fromEvent(window, 'keydown')
- .pipe(
- filter(
- event =>
- // Slash shortcut (if no input element is focused)
- (event.key === '/' &&
- !!document.activeElement &&
- !['INPUT', 'TEXTAREA'].includes(document.activeElement.nodeName)) ||
- // Cmd/Ctrl+P shortcut
- ((event.metaKey || event.ctrlKey) && event.key === 'p') ||
- // Cmd/Ctrl+Shift+F shortcut
- ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key === 'f')
- ),
- switchMap(event => {
- event.preventDefault()
- // Use selection as query
- const selection = window.getSelection().toString()
- if (selection) {
- return new Observable(observer =>
- this.setState(
- {
- // query: selection, TODO(sqs): add back this behavior
- suggestions: [],
- selectedSuggestion: -1,
- },
- () => {
- observer.next()
- observer.complete()
- }
- )
- )
- }
- return [undefined]
- })
- )
- .subscribe(() => {
- if (this.inputElement) {
- // Select all input
- this.inputElement.focus()
- this.inputElement.setSelectionRange(0, this.inputElement.value.length)
- }
- })
- )
-
- // Allow other components to update the query (e.g., to be relevant to what the user is
- // currently viewing).
- this.subscriptions.add(
- queryUpdates.pipe(distinctUntilChanged()).subscribe(query => this.props.onChange(query))
- )
-
- /** Whenever the URL query has a "focus" property, remove it and focus the query input. */
- this.subscriptions.add(
- this.componentUpdates.pipe(startWith(props)).subscribe(props => {
- if (this.inputElement) {
- const value = this.inputElement.value
- if (value !== props.value) {
- this.inputElement.value = props.value
- this.focusInputAndPositionCursorAtEnd()
- }
- }
- })
- )
- }
- }
-
- public componentDidMount(): void {
- switch (this.props.autoFocus) {
- case 'cursor-at-end':
- this.focusInputAndPositionCursorAtEnd()
- break
- }
- }
-
- public componentWillReceiveProps(newProps: Props): void {
- this.componentUpdates.next(newProps)
- }
-
- public componentWillUnmount(): void {
- this.subscriptions.unsubscribe()
- }
-
- public componentDidUpdate(prevProps: Props, prevState: State): void {
- // Check if selected suggestion is out of view
- scrollIntoView(this.suggestionListElement, this.selectedSuggestionElement)
- }
-
- public render(): JSX.Element | null {
- const showSuggestions =
- this.props.value.length >= QueryInputForModal.SUGGESTIONS_QUERY_MIN_LENGTH &&
- this.state.inputFocused &&
- !this.state.hideSuggestions &&
- this.state.suggestions.length !== 0
-
- return (
-
-
(this.inputElement = ref!)}
- />
- {this.state.loading &&
}
- {showSuggestions && (
-
- {this.state.suggestions.map((suggestion, i) => {
- const isSelected = this.state.selectedSuggestion === i
- const onRef = (ref: HTMLLIElement | null) => {
- if (isSelected) {
- this.selectedSuggestionElement = ref || undefined
- }
- }
- return (
- this.selectSuggestion(suggestion)}
- liRef={onRef}
- />
- )
- })}
-
- )}
-
- )
- }
-
- // Handle the cursor changing in the input field and
- // allow the user to type after the string changes.
- // Used in modal on homepage.
- private changeCursor: React.FocusEventHandler = e => {
- setTimeout(() => {
- this.inputFocuses.next()
- this.setState({ inputFocused: true })
- }, 100)
- }
- private setSuggestionListElement = (ref: HTMLElement | null): void => {
- this.suggestionListElement = ref || undefined
- }
-
- private selectSuggestion = (suggestion: Suggestion): void => {
- // 🚨 PRIVACY: never provide any private data in { code_search: { suggestion: { type } } }.
- eventLogger.log('SearchSuggestionSelected', {
- code_search: {
- suggestion: {
- type: suggestion.type,
- url: suggestion.url,
- },
- },
- })
-
- this.props.history.push(suggestion.url)
-
- this.suggestionsHidden.next()
- this.setState({ hideSuggestions: true, selectedSuggestion: -1 })
- }
-
- private focusInputAndPositionCursorAtEnd(): void {
- if (this.inputElement) {
- // Focus the input element and set cursor to the end
- this.inputElement.focus()
- this.inputElement.setSelectionRange(this.inputElement.value.length, this.inputElement.value.length)
- }
- }
-
- private onInputChange: React.ChangeEventHandler = event => {
- if (!this.hasLoggedFirstInput) {
- eventLogger.log('SearchInitiated')
- this.hasLoggedFirstInput = true
- }
- this.inputValues.next(event.currentTarget.value)
- }
-
- private onInputBlur: React.FocusEventHandler = event => {
- this.suggestionsHidden.next()
- this.setState({ inputFocused: false, loading: false, hideSuggestions: true })
- }
-
- private onInputKeyDown: React.KeyboardEventHandler = event => {
- event.persist()
- this.inputKeyDowns.next(event)
- switch (event.key) {
- case Key.Escape: {
- this.suggestionsHidden.next()
- this.setState({ loading: false, hideSuggestions: true, selectedSuggestion: -1 })
- break
- }
- case Key.ArrowDown: {
- event.preventDefault()
- this.moveSelection(1)
- break
- }
- case Key.ArrowUp: {
- event.preventDefault()
- this.moveSelection(-1)
- break
- }
- case Key.Enter: {
- if (this.state.selectedSuggestion === -1) {
- // Submit form and hide suggestions
- this.suggestionsHidden.next()
- this.setState({ hideSuggestions: true })
- break
- }
-
- // Select suggestion
- event.preventDefault()
- if (this.state.suggestions.length === 0) {
- break
- }
- this.selectSuggestion(this.state.suggestions[Math.max(this.state.selectedSuggestion, 0)])
- this.setState({ hideSuggestions: true })
- break
- }
- }
- }
-
- private moveSelection(steps: number): void {
- this.setState({
- selectedSuggestion: Math.max(
- Math.min(this.state.selectedSuggestion + steps, this.state.suggestions.length - 1),
- -1
- ),
- })
- }
-}
diff --git a/web/src/search/input/README.md b/web/src/search/input/README.md
deleted file mode 100644
index 3f259071173..00000000000
--- a/web/src/search/input/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Components for areas in the app that expose a search input
diff --git a/web/src/tracking/services/serverAdminWrapper.tsx b/web/src/tracking/services/serverAdminWrapper.tsx
index 02fa3e2ed5a..0352f63fa0b 100644
--- a/web/src/tracking/services/serverAdminWrapper.tsx
+++ b/web/src/tracking/services/serverAdminWrapper.tsx
@@ -10,7 +10,7 @@ class ServerAdminWrapper {
private isAuthenicated = false
constructor() {
- if (!window.context.sourcegraphDotComMode) {
+ if (window.context && !window.context.sourcegraphDotComMode) {
authenticatedUser.subscribe(user => {
if (user) {
this.isAuthenicated = true
diff --git a/web/src/tracking/services/telligentWrapper.tsx b/web/src/tracking/services/telligentWrapper.tsx
index 1f0a2e3fe55..1d055ea0dfc 100644
--- a/web/src/tracking/services/telligentWrapper.tsx
+++ b/web/src/tracking/services/telligentWrapper.tsx
@@ -11,7 +11,7 @@ class TelligentWrapper {
constructor() {
// Never log anything in self-hosted Sourcegraph instances.
- if (!window.context.sourcegraphDotComMode) {
+ if (!window.context || !window.context.sourcegraphDotComMode) {
return
}
diff --git a/yarn.lock b/yarn.lock
index 945f12c5ebe..61dbcf70c21 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2046,6 +2046,11 @@
"@types/events" "*"
"@types/node" "*"
+"@types/classnames@^2.2.7":
+ version "2.2.7"
+ resolved "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.7.tgz#fb68cc9be8487e6ea5b13700e759bfbab7e0fefd"
+ integrity sha512-rzOhiQ55WzAiFgXRtitP/ZUT8iVNyllEpylJ5zHzR4vArUvMB39GTk+Zon/uAM0JxEFAWnwsxC2gH8s+tZ3Myg==
+
"@types/cli-color@^0.3.29":
version "0.3.29"
resolved "https://registry.npmjs.org/@types/cli-color/-/cli-color-0.3.29.tgz#c83a71fe02c8c7e1ccec048dd6a2458d1f6c96ea"
@@ -4663,7 +4668,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-classnames@^2.2.3, classnames@^2.2.5:
+classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6:
version "2.2.6"
resolved "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==