Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onboarding improvements: No local changes blank slate #6445

Merged
merged 49 commits into from
Jan 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
ba14301
Let's start with a feature flag
niik Dec 18, 2018
09b585c
Gotta start somewhere
niik Dec 18, 2018
d32d75d
Extract and export getPlatformSpecificNameOrSymbolForModifier for re-use
niik Dec 18, 2018
6e1ac1e
Wire up and use menu as backing store
niik Dec 18, 2018
582593e
Some initial styling
niik Dec 18, 2018
5c776f4
Split it out into components and wire up clicking
niik Dec 18, 2018
26ad275
Auto doesn't seem to do it
niik Dec 18, 2018
2c3214d
Don't render menu backed action if it's not enabled
niik Dec 18, 2018
2f06c7a
Centralize handling of kbd tags
niik Dec 18, 2018
5ae88a7
More styling
niik Dec 18, 2018
68922da
Add view on GitHub action
niik Dec 18, 2018
5d8aa05
Give it some space
niik Dec 18, 2018
a88d0ee
Add open in external editor action
niik Dec 18, 2018
50c9dc5
Refactor scss
niik Dec 18, 2018
4643aa4
Prepare for the repository actions
niik Dec 18, 2018
5a89de1
These are all covered globally now
niik Dec 19, 2018
d5b70fc
Grammar
niik Dec 19, 2018
684f6e0
Separate discoverability and description
niik Dec 19, 2018
ee382f2
Terse it up
niik Dec 19, 2018
66d6238
Use default border color except in toast notifications
niik Dec 19, 2018
1944567
A little margin between kdb elements
niik Dec 19, 2018
b9e8857
Primary actions
niik Dec 19, 2018
6d6be11
Moar kbd styling
niik Dec 19, 2018
77f48e3
Less tho
niik Dec 19, 2018
21bca44
Initial publish action
niik Dec 19, 2018
7db533d
Initial publish branch action
niik Dec 19, 2018
ed2a18f
Tweak discoverability for publish actions
niik Dec 19, 2018
3875648
Merge branch 'development' into no-changes-blankslate
niik Jan 8, 2019
093c6ec
Add pull repository action
niik Jan 8, 2019
1e7d835
Initial push blankslate action
niik Jan 8, 2019
87d34bc
Ahead, not behind
niik Jan 8, 2019
7525dc3
Language tweaks
niik Jan 8, 2019
792d8c1
Spaces
niik Jan 8, 2019
0bbacb6
No point in doing any remote actions if we don't have a branch
niik Jan 8, 2019
3508989
Don't render if menu item is disabled
niik Jan 8, 2019
23008cf
Initial create PR action
niik Jan 8, 2019
390d2c4
Disable actions when corresponding menu items are disabled
niik Jan 9, 2019
c3e8717
Don't render view on github if not github repo
niik Jan 9, 2019
470dee6
Don't render open in external editor if no editor available
niik Jan 9, 2019
aa1c113
:art: cleanup
niik Jan 9, 2019
5e0c5d2
:book: props
niik Jan 9, 2019
49a005d
:book: IMenuItemInfo
niik Jan 9, 2019
ab75fbd
:fire: unused
niik Jan 9, 2019
f50720a
:book: blankslate action props
niik Jan 9, 2019
ae3ebf9
:book: MenuBackedBlankSlate props
niik Jan 9, 2019
d66bc82
Open in external editor takes precedence
niik Jan 9, 2019
760187f
Merge branch 'development' into no-changes-blankslate
niik Jan 9, 2019
b6bf6bd
Add overflow in high zoom levels
niik Jan 10, 2019
755bb44
Responsive design when zooming
niik Jan 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions app/src/lib/feature-flag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,12 @@ export function enableGitProtocolVersionTwo(): boolean {
export function enableReadmeOverwriteWarning(): boolean {
return enableBetaFeatures()
}

/**
* Whether or not to activate the new, improved, blank slate
* shown when the user doesn't have any local changes in their
* repository.
*/
export function enableNewNoChangesBlankslate(): boolean {
return enableBetaFeatures()
}
41 changes: 41 additions & 0 deletions app/src/lib/menu-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,44 @@ export interface IMenuItem {
*/
readonly role?: string
}

/**
* Converts Electron accelerator modifiers to their platform specific
* name or symbol.
*
* Example: CommandOrControl becomes either '⌘' or 'Ctrl' depending on platform.
*
* See https://github.com/electron/electron/blob/fb74f55/docs/api/accelerator.md
*/
export function getPlatformSpecificNameOrSymbolForModifier(
niik marked this conversation as resolved.
Show resolved Hide resolved
modifier: string
): string {
switch (modifier.toLowerCase()) {
case 'cmdorctrl':
case 'commandorcontrol':
return __DARWIN__ ? '⌘' : 'Ctrl'

case 'ctrl':
case 'control':
return __DARWIN__ ? '⌃' : 'Ctrl'

case 'shift':
return __DARWIN__ ? '⇧' : 'Shift'
case 'alt':
return __DARWIN__ ? '⌥' : 'Alt'

// Mac only
case 'cmd':
case 'command':
return '⌘'
case 'option':
return '⌥'

// Special case space because no one would be able to see it
case ' ':
return 'Space'
}

// Not a known modifier, likely a normal key
return modifier
}
40 changes: 1 addition & 39 deletions app/src/ui/app-menu/menu-list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as classNames from 'classnames'
import { Octicon, OcticonSymbol } from '../octicons'
import { MenuItem } from '../../models/app-menu'
import { AccessText } from '../lib/access-text'
import { getPlatformSpecificNameOrSymbolForModifier } from '../../lib/menu-item'

interface IMenuListItemProps {
readonly item: MenuItem
Expand Down Expand Up @@ -34,45 +35,6 @@ interface IMenuListItemProps {
readonly renderSubMenuArrow?: boolean
}

/**
* Converts Electron accelerator modifiers to their platform specific
* name or symbol.
*
* Example: CommandOrControl becomes either '⌘' or 'Ctrl' depending on platform.
*
* See https://github.com/electron/electron/blob/fb74f55/docs/api/accelerator.md
*/
function getPlatformSpecificNameOrSymbolForModifier(modifier: string): string {
switch (modifier.toLowerCase()) {
case 'cmdorctrl':
case 'commandorcontrol':
return __DARWIN__ ? '⌘' : 'Ctrl'

case 'ctrl':
case 'control':
return __DARWIN__ ? '⌃' : 'Ctrl'

case 'shift':
return __DARWIN__ ? '⇧' : 'Shift'
case 'alt':
return __DARWIN__ ? '⌥' : 'Alt'

// Mac only
case 'cmd':
case 'command':
return '⌘'
case 'option':
return '⌥'

// Special case space because no one would be able to see it
case ' ':
return 'Space'
}

// Not a known modifier, likely a normal key
return modifier
}

/**
* Returns a platform specific human readable version of an Electron
* accelerator string. See getPlatformSpecificNameOrSymbolForModifier
Expand Down
1 change: 1 addition & 0 deletions app/src/ui/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2015,6 +2015,7 @@ export class App extends React.Component<IAppProps, IAppState> {
accounts={state.accounts}
externalEditorLabel={externalEditorLabel}
onOpenInExternalEditor={this.openFileInExternalEditor}
appMenu={this.state.appMenuState[0]}
/>
)
} else if (selectedState.type === SelectionType.CloningRepository) {
Expand Down
88 changes: 88 additions & 0 deletions app/src/ui/changes/blankslate-action.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import * as React from 'react'
import * as classNames from 'classnames'
import { Button } from '../lib/button'

interface IBlankSlateActionProps {
/**
* The title, or "header" text for a blank slate
* action.
*/
readonly title: string

/**
* An optional description to be rendered directly
* underneath the title.
*/
readonly description?: string | JSX.Element

/**
* A text or set of elements used to present information
* to the user about how and where to access the action
* outside of the blank slate action.
*/
readonly discoverabilityContent: string | JSX.Element

/**
* The text, or "label", for the action button.
*/
readonly buttonText: string | JSX.Element

/**
* A callback which is invoked when the user clicks
* or activates the action using their keyboard.
*/
readonly onClick: () => void

/**
* The type of action, currently supported actions are
* normal, and primary. Primary actions are visually
* distinct from normal actions in order to stand out
* as a highly probable next step action.
*/
readonly type?: 'normal' | 'primary'

/**
* Whether or not the action should be disabled. Disabling
* the action means that the button will no longer be
* clickable.
*/
readonly disabled?: boolean
}

/**
* A small container component for rendering an "action" in a blank
* slate view. An action is usally contained within an action group
* which visually connects one or more actions. An action component
* has a title, a description, and a button label.
*/
export class BlankslateAction extends React.Component<
IBlankSlateActionProps,
{}
> {
public render() {
const primary = this.props.type === 'primary'
const cn = classNames('blankslate-action', { primary })
const description =
this.props.description === undefined ? (
undefined
) : (
<p className="description">{this.props.description}</p>
)
return (
<div className={cn}>
<div className="text-wrapper">
<h2>{this.props.title}</h2>
{description}
<p className="discoverability">{this.props.discoverabilityContent}</p>
</div>
<Button
type={primary ? 'submit' : undefined}
onClick={this.props.onClick}
disabled={this.props.disabled}
>
{this.props.buttonText}
</Button>
</div>
)
}
}
87 changes: 87 additions & 0 deletions app/src/ui/changes/menu-backed-blankslate-action.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import * as React from 'react'
import { BlankslateAction } from './blankslate-action'
import { MenuIDs } from '../../main-process/menu'
import { executeMenuItemById } from '../main-process-proxy'

interface IMenuBackedBlankSlateActionProps {
/**
* The id of the menu item backing this action.
* When the action is invoked the menu item specified
* by this id will be executed.
*/
readonly menuItemId: MenuIDs

/**
* The title, or "header" text for a blank slate
* action.
*/
readonly title: string

/**
* An optional description to be rendered directly
* underneath the title.
*/
readonly description?: string | JSX.Element

/**
* A text or set of elements used to present information
* to the user about how and where to access the action
* outside of the blank slate action.
*/
readonly discoverabilityContent: string | JSX.Element

/**
* The text, or "label", for the action button.
*/
readonly buttonText: string | JSX.Element

/**
* The type of action, currently supported actions are
* normal, and primary. Primary actions are visually
* distinct from normal actions in order to stand out
* as a highly probable next step action.
*/
readonly type?: 'normal' | 'primary'

/**
* Whether or not the action should be disabled. Disabling
* the action means that the button will no longer be
* clickable.
*/
readonly disabled?: boolean
}

/**
* A small container component for rendering an "action" in a blank
* slate view. An action is usally contained within an action group
* which visually connects one or more actions. An action component
* has a title, a description, and a button label.
*
* A menu backed blankslate action differs from a normal blankslate
* action in that it's directly linked to a menu item in the
* application menu and invoking a menu backed action will execute
* the menu item backing it without a need for consumers to specify
* an onClick callback.
*/
export class MenuBackedBlankslateAction extends React.Component<
IMenuBackedBlankSlateActionProps,
{}
> {
public render() {
return (
<BlankslateAction
title={this.props.title}
description={this.props.description}
discoverabilityContent={this.props.discoverabilityContent}
buttonText={this.props.buttonText}
onClick={this.onClick}
type={this.props.type}
disabled={this.props.disabled}
/>
)
}

private onClick = () => {
executeMenuItemById(this.props.menuItemId)
}
}
Loading