Skip to content

Commit 09fc025

Browse files
eanders-msganicke
andauthored
sign in dialog refresh (microsoft#8373)
* sign in dialog refresh * 7.1.17 * Add sign-in and cloud-sync docs * A few small edits * Some more small edits * prepositional changes * left-justify modal actions (the new ones) * Update sign-in.md * Update sign-in.md Co-authored-by: Galen Nickel <gnickel@aquent.com>
1 parent 52515e8 commit 09fc025

File tree

5 files changed

+109
-88
lines changed

5 files changed

+109
-88
lines changed

common-docs/identity/cloud-sync.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Cloud Synchronization in MakeCode
2+
3+
**Note**: This feature only available in [**MakeCode Arcade**](https://arcade.makecode.com).
4+
5+
## What is Cloud Sync?
6+
7+
Cloud Synchronization, or Cloud Sync, is a feature available to signed in users that lets MakeCode save your projects in the cloud, where they're available anywhere you can sign in to MakeCode.
8+
9+
## How do I enable Cloud Sync?
10+
11+
All you need to do is sign in to MakeCode with your Microsoft Account and Cloud Sync is automatically enabled. Learn more about signing in to MakeCode [here](/identity/sign-in).
12+
13+
## Does it cost money?
14+
15+
Nope! Cloud Sync completely is free.
16+
17+
## What are the limits?
18+
19+
Individual projects must be less than 512K bytes in size to be synced to cloud. You may store up to 1000 projects in the cloud.
20+
21+
## When is a project saved to the cloud?
22+
23+
Projects are transferred to the cloud the next time they're opened for editing. When you first sign in, your local projects remain local. To transfer a project to the cloud, just open it in the editor. The rest is automatic.
24+
25+
## When is a project updated from the cloud?
26+
27+
Your project list is refreshed when you navigate to the home screen. When a project is opened, a quick cloud check is done to make sure you're opening the latest version.
28+
29+
## How can I tell if a project is stored in the cloud?
30+
31+
In your project list, look for a little cloud icon on the project card. If it's there, your project is backed up to the cloud. In the editor, look for the cloud status indicator in the lower left. You should notice it automatically saving to cloud as you edit your project.
32+
33+
## What if I edit the project in two places?
34+
35+
If you're editing a project in two places at the same time, you may make changes that conflict. When this happens, the editor that detected the conflict will resolve it by making a copy of the project and applying the conflicting change to the new one. At this point the two browsers will be editing different projects.
36+
37+
## Is anything else saved to cloud?
38+
39+
If you've set your High Contrast or Language settings, they will be cloud-synchronized too.
40+

common-docs/identity/sign-in.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Microsoft Accounts and MakeCode
2+
3+
**Note**: This feature only available in [**MakeCode Arcade**](https://arcade.makecode.com).
4+
5+
## What is a Microsoft Account?
6+
7+
A Microsoft Account, or MSA, is the personal user account you create when you want to sign into Microsoft services like outlook.com, Xbox, Skype, etc. Read more [here](https://aka.ms/AAdd6f8).
8+
9+
## How does it work in MakeCode?
10+
11+
A number of new features are coming that will only be available to signed-in users. These features need to know your identity so they can do things for you like store data in the cloud, and connect you to other users. The first of these features is one we're calling [Cloud Sync](/identity/cloud-sync). With Cloud Sync, when you're signed into MakeCode, we'll store your projects in the cloud where they're accessible from anywhere.
12+
13+
## Is it required?
14+
15+
No. Sign in only if you want to take advantage of features like Cloud Sync.
16+
17+
## Does it cost money?
18+
19+
Nope! Creating an MSA account is free. Using MakeCode is also free. As a reminder, MSA accounts work across a range of Microsoft products and services, so you can use it outside MakeCode. Some of these products and services may not be free (Minecraft Marketplace content, for example), but this is outside the MakeCode ecosystem.
20+
21+
## What will other users see?
22+
23+
Your signed in status is visible only to you. In the future we may add features that allow others to see your presence. When that time comes, we would ask you to create a MakeCode Profile so that your name and picture are decoupled from your MSA profile.
24+
25+
## Do I already have a Microsoft Account?
26+
27+
It is possible! Do you play Minecraft, game on an Xbox, subscribe to Office 365, or use any other Microsoft products or services? If so, you probably already have a Microsoft Account.
28+
29+
## Does this mean I have to create a new email address?
30+
31+
No. You can create an MSA using your current email address if it is not hosted by Microsoft (e.g.: Gmail, Yahoo Mail, and others). When creating your MSA account, just enter your existing email address.
32+
33+
## Can I use my school or work account?
34+
35+
If your school or employer's email system is managed by Microsoft Azure Active Directory, then generally it should work in MakeCode subject to restrictions put in place by your IT dept.

theme/common.less

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,10 @@ p.ui.font.small {
12171217
margin-left: 4px;
12181218
}
12191219

1220+
.ui.modal .actions .left-action {
1221+
float: left;
1222+
}
1223+
12201224
.download-callout {
12211225
background-color: #EAE7FF;
12221226
color: #4C309D;
@@ -1922,46 +1926,6 @@ div.simframe.ui.embed {
19221926
-ms-interpolation-mode: nearest-neighbor;
19231927
}
19241928

1925-
/* Sign in dialog */
1926-
.ui.modal.signindialog {
1927-
.content {
1928-
padding: 24px 20px;
1929-
}
1930-
1931-
div.description {
1932-
margin-bottom: 20px;
1933-
}
1934-
1935-
div.warning {
1936-
background-color: #F5BC5F;
1937-
padding: 6px;
1938-
margin-bottom: 20px;
1939-
}
1940-
1941-
div.container {
1942-
display: grid;
1943-
row-gap: 10px;
1944-
grid-template-rows: 36px auto;
1945-
grid-template-columns: auto;
1946-
justify-content: center;
1947-
1948-
button {
1949-
margin: 0;
1950-
}
1951-
1952-
div.prompt {
1953-
justify-self: center;
1954-
}
1955-
1956-
div.providers {
1957-
display: grid;
1958-
row-gap: 20px;
1959-
grid-template-rows: auto;
1960-
justify-content: center;
1961-
}
1962-
}
1963-
}
1964-
19651929
.ui.menu .item.sign-in-dropdown {
19661930
padding-left: 0rem;
19671931
padding-right: .3rem;

webapp/src/identity.tsx

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -41,62 +41,42 @@ export class LoginDialog extends auth.Component<LoginDialogProps, LoginDialogSta
4141
this.setState({ visible: false });
4242
}
4343

44+
private async signInAsync(provider: pxt.AppCloudProvider): Promise<void> {
45+
pxt.tickEvent(`identity.loginClick`, { provider: provider.name, rememberMe: this.state.rememberMe.toString() });
46+
await auth.loginAsync(provider.id, this.state.rememberMe, {
47+
hash: this.state.continuationHash
48+
});
49+
}
50+
4451
renderCore() {
4552
const { visible } = this.state;
46-
const providers = pxt.auth.identityProviders();
53+
const msft = pxt.auth.identityProvider("microsoft");
54+
55+
const buttons: sui.ModalButton[] = [];
56+
buttons.push({
57+
label: lf("Sign in"),
58+
onclick: async () => await this.signInAsync(msft),
59+
icon: "checkmark",
60+
approveButton: true,
61+
className: "positive"
62+
});
63+
64+
const actions: JSX.Element[] = [];
65+
actions.push(<sui.PlainCheckbox label={lf("Remember me")} onChange={this.handleRememberMeChanged} />);
4766

4867
return (
4968
<sui.Modal isOpen={visible} className="signindialog" size="tiny"
50-
onClose={this.hide} dimmer={true}
51-
closeIcon={true} header={lf("Sign in or Signup")}
69+
onClose={this.hide} dimmer={true} buttons={buttons} actions={actions}
70+
closeIcon={true} header={lf("Sign into {0}", pxt.appTarget.appTheme.organizationText)}
5271
closeOnDimmerClick closeOnDocumentClick closeOnEscape>
53-
<div className="description">
54-
<p>{lf("Connect an existing account in order to sign in or signup for the first time.")} <sui.Link className="ui" text={lf("Learn more")} icon="external alternate" ariaLabel={lf("Learn more")} href="https://aka.ms/cloudsave" target="_blank" onKeyDown={sui.fireClickOnEnter} /></p>
55-
</div>
56-
<div className="container">
57-
<div className="prompt">
58-
<p>Choose an account to connect:</p>
59-
</div>
60-
<div className="providers">
61-
<div className="provider">
62-
{providers.map((p, key) => (
63-
<ProviderButton key={key} provider={p} rememberMe={this.state.rememberMe} continuationHash={this.state.continuationHash} />
64-
))}
65-
</div>
66-
<div className="remember-me">
67-
<sui.PlainCheckbox label={lf("Remember me")} onChange={this.handleRememberMeChanged} />
68-
</div>
69-
</div>
70-
</div>
72+
<p>{lf("Sign in with your Microsoft Account. We'll save your projects to the cloud, where they're accessible from anywhere.")}</p>
73+
<p>{lf("Don't have a Microsoft Account? Start signing in to create one!")}</p>
74+
<sui.Link className="ui" text={lf("Learn more")} icon="external alternate" ariaLabel={lf("Learn more")} href="/identity/sign-in" target="_blank" onKeyDown={sui.fireClickOnEnter} />
7175
</sui.Modal>
7276
);
7377
}
7478
}
7579

76-
type ProviderButtonProps = {
77-
provider: pxt.AppCloudProvider;
78-
rememberMe: boolean;
79-
continuationHash: string;
80-
};
81-
82-
class ProviderButton extends data.PureComponent<ProviderButtonProps, {}> {
83-
84-
handleLoginClicked = async () => {
85-
const { provider, rememberMe } = this.props;
86-
pxt.tickEvent(`identity.loginClick`, { provider: provider.name, rememberMe: rememberMe.toString() });
87-
await auth.loginAsync(provider.id, rememberMe, {
88-
hash: this.props.continuationHash
89-
});
90-
}
91-
92-
renderCore() {
93-
const { provider } = this.props;
94-
return (
95-
<sui.Button icon={`xicon ${provider.id}`} text={provider.name} onClick={this.handleLoginClicked} />
96-
);
97-
}
98-
}
99-
10080
export type UserMenuProps = ISettingsProps & {
10181
continuationHash?: string;
10282
};
@@ -192,7 +172,7 @@ export class UserMenu extends auth.Component<UserMenuProps, UserMenuState> {
192172
</sui.Item>
193173
: undefined}
194174
{showGhUnlink ? <div className="ui divider"></div> : undefined}
195-
{!loggedIn ? <sui.Item role="menuitem" text={lf("Sign in")} onClick={this.handleLoginClicked}/> : undefined}
175+
{!loggedIn ? <sui.Item role="menuitem" text={lf("Sign in")} onClick={this.handleLoginClicked} /> : undefined}
196176
{loggedIn ? <sui.Item role="menuitem" text={lf("Sign out")} onClick={this.handleLogoutClicked} /> : undefined}
197177
</sui.DropdownMenu>
198178
);

webapp/src/sui.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,7 @@ export interface ModalProps extends ReactModal.Props {
11671167

11681168
helpUrl?: string;
11691169
headerActions?: JSX.Element[];
1170+
actions?: JSX.Element[];
11701171
buttons?: ModalButton[];
11711172
onPositionChanged?: Function;
11721173
allowResetFocus?: boolean;
@@ -1333,9 +1334,10 @@ export class Modal extends data.Component<ModalProps, ModalState> {
13331334
<div id={this.id + 'desc'} className={`${longer ? 'scrolling' : ''} ${headerActions ? 'has-actions' : ''} content`}>
13341335
{children}
13351336
</div>
1336-
{!isFullscreen && this.props.buttons && this.props.buttons.length > 0 ?
1337+
{!isFullscreen && (this.props.actions && this.props.actions.length || this.props.buttons && this.props.buttons.length) ?
13371338
<div className="actions">
1338-
{this.props.buttons.map(action =>
1339+
{this.props.actions?.map(action => <div className="left-action">{action}</div>)}
1340+
{this.props.buttons?.map(action =>
13391341
action.url ?
13401342
<Link
13411343
key={`action_${action.label}`}

0 commit comments

Comments
 (0)