Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions react-common/components/profile/SignInModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ export interface SignInModalProps {
}
resolvePath?: (path: string) => string
mode?: "signin" | "signup"
lastUsedIdentityProvider?: pxt.IdentityProviderId
}

export const SignInModal = (props: SignInModalProps) => {
const { onSignIn, onClose, appMessage, dialogMessages, hideDismissButton } = props
const { onSignIn, onClose, appMessage, dialogMessages, hideDismissButton, lastUsedIdentityProvider } = props
const { signInMessage, signUpMessage } = dialogMessages || {
signInMessage: lf("Sign in to save your progress and access your work anytime, anywhere."),
signUpMessage: lf("Join now to save your progress and access your work anytime, anywhere.")
Expand Down Expand Up @@ -70,19 +71,24 @@ export const SignInModal = (props: SignInModalProps) => {
<div className='signin-body'>
<div className='providers'>
{pxt.auth.identityProviders().map((provider, index) => {
const isLastUsedProvider = provider.id === lastUsedIdentityProvider
const title =
mode === "signin"
? lf("Continue with {0}", provider.name)
: lf("Sign up with {0}", provider.name)
const ariaLabel = isLastUsedProvider
? lf("{0}. You last used this option.", title)
: title
return (
<Button
key={index}
className='provider'
onClick={() => onSignIn(provider, rememberMe)}
title={title}
ariaLabel={title}
ariaLabel={ariaLabel}
label={
<div className='label'>
{isLastUsedProvider && <div className='ui orange right ribbon label last-used-ribbon' aria-hidden="true">{lf("Last used")}</div>}
<div>
<img className='logo' src={resolvePath(provider.icon)} />
</div>
Expand Down
15 changes: 14 additions & 1 deletion react-common/styles/profile/profile.less
Original file line number Diff line number Diff line change
Expand Up @@ -400,18 +400,31 @@
background-color: var(--pxt-neutral-background1);
color: var(--pxt-neutral-foreground1);
border: solid 1px var(--pxt-neutral-foreground1);
position: relative;
overflow: visible;

.label {
display: flex;
flex-direction: row;
gap: 1rem;
align-items: center;

.last-used-ribbon {
position: absolute;
top: -1rem;
right: -1rem;
left: auto;
transform: none;
margin-right: 0;
z-index: 1;
}

.logo {
width: 1.25rem;
}

.title {
align-self: center;
text-align: left;
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions webapp/src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const COLOR_THEME_IDS = `${USER_PREF_MODULE}:${FIELD_COLOR_THEME_IDS}`
export const LANGUAGE = `${USER_PREF_MODULE}:${FIELD_LANGUAGE}`
export const READER = `${USER_PREF_MODULE}:${FIELD_READER}`
export const HAS_USED_CLOUD = "has-used-cloud"; // Key into local storage to see if this computer has logged in before
export const LAST_IDENTITY_PROVIDER = "last-identity-provider";

export class Component<TProps, TState> extends data.Component<TProps, TState> {
public getUserProfile(): pxt.auth.UserProfile {
Expand All @@ -46,6 +47,11 @@ class AuthClient extends pxt.auth.AuthClient {
if (!!workspace.getWorkspaceType())
await cloud.syncAsync();
pxt.storage.setLocal(HAS_USED_CLOUD, "true");

const providerId = pxt.auth.identityProviderId(state.profile);
if (providerId) {
pxt.storage.setLocal(LAST_IDENTITY_PROVIDER, providerId);
}
}
protected onSignedOut(): Promise<void> {
core.infoNotification(lf("Signed out"));
Expand Down Expand Up @@ -195,6 +201,11 @@ export function userPreferences(): pxt.auth.UserPreferences {
return data.getData<pxt.auth.UserPreferences>(USER_PREFERENCES);
}

export function lastUsedIdentityProviderId(): pxt.IdentityProviderId | undefined {
const providerId = pxt.storage.getLocal(LAST_IDENTITY_PROVIDER) as pxt.IdentityProviderId;
return pxt.auth.identityProvider(providerId) ? providerId : undefined;
}

export async function authCheckAsync(): Promise<pxt.auth.UserProfile | undefined> {
const cli = await clientAsync();
return await cli?.authCheckAsync();
Expand Down
8 changes: 7 additions & 1 deletion webapp/src/identity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,15 @@ export class LoginDialog extends auth.Component<LoginDialogProps, LoginDialogSta

renderCore() {
const { visible, dialogMessages } = this.state;
const lastUsedIdentityProvider = auth.lastUsedIdentityProviderId();

return <>
{visible && <SignInModal onClose={this.hide} onSignIn={this.signInAsync} dialogMessages={dialogMessages} />}
{visible && <SignInModal
onClose={this.hide}
onSignIn={this.signInAsync}
dialogMessages={dialogMessages}
lastUsedIdentityProvider={lastUsedIdentityProvider}
/>}
</>;
}
}
Expand Down
Loading