Skip to content

Commit

Permalink
[stable7.3] Cherry pick badge fixes (#8602)
Browse files Browse the repository at this point in the history
* Adding certificate preview to the rewards modal and skillmap tests (#8592)

* Adding certificate preview to the rewards modal and skillmap tests

* Fix lint and remove extra css

* Add the ability to specify a name for the badge

* Make loading start earlier and add locked badges (#8600)

* Make loading start earlier and add locked badges

* pr feedback

* Fix the tilemap wall cursor (#8601)
  • Loading branch information
riknoll authored Nov 17, 2021
1 parent 5b3ce84 commit 94051a7
Show file tree
Hide file tree
Showing 16 changed files with 332 additions and 55 deletions.
8 changes: 7 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,10 @@ const copySkillmapHtml = () => rimraf("webapp/public/skillmap.html")

const skillmap = gulp.series(cleanSkillmap, buildSkillmap, gulp.series(copySkillmapCss, copySkillmapJs, copySkillmapHtml));

const buildSkillmapTests = () => compileTsProject("skillmap/tests", "built/tests");
const runSkillmapTests = () => exec("./node_modules/.bin/mocha ./built/tests/tests/skillmapParser.spec.js", true)

const testSkillmap = gulp.series(buildSkillmapTests, runSkillmapTests);

/********************************************************
Tests and Linting
Expand Down Expand Up @@ -652,7 +656,8 @@ const testAll = gulp.series(
testpytraces,
testtutorials,
testlanguageservice,
karma
karma,
testSkillmap
)

function testTask(testFolder, testFile) {
Expand Down Expand Up @@ -723,6 +728,7 @@ exports.webapp = gulp.series(
browserifyWebapp
)

exports.skillmapTest = testSkillmap;
exports.updatestrings = updatestrings;
exports.updateblockly = copyBlockly;
exports.lint = lint
Expand Down
1 change: 1 addition & 0 deletions localtypings/pxtarget.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,7 @@ declare namespace pxt.auth {
type: BadgeType;
title: string;
image: string;
lockedImage?: string;
timestamp?: number;
}

Expand Down
8 changes: 5 additions & 3 deletions react-common/components/profile/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ export const Badge = (props: BadgeProps) => {
onClick(badge);
})

const image = (disabled && badge.lockedImage) || badge.image;
const alt = disabled ? pxt.U.lf("Locked '{0}' badge", badge.title) : badge.title;

return (
<div className={`profile-badge ${disabled ? "disabled" : ""} ${onClick ? "clickable" : ""}`}
<div className={`profile-badge ${onClick ? "clickable" : ""}`}
role={onClick ? "button" : undefined}
tabIndex={onClick ? 0 : undefined}
title={lf("{0} Badge", badge.title)}
onClick={onBadgeClick}
onKeyDown={fireClickOnEnter}>
{isNew && <div className="profile-badge-notification">{pxt.U.lf("New!")}</div>}
<img src={badge.image} alt={badge.title} />
{disabled && <i className="ui huge icon lock" />}
<img src={image} alt={alt} />
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion react-common/components/profile/BadgeInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const badgeDescription = (badge: pxt.auth.Badge) => {
case "skillmap-completion":
return <span>{jsxLF(
lf("Completing {0}"),
<a target="_blank" href={sourceURLToSkillmapURL(badge.sourceURL)}>{pxt.U.rlf(badge.title)}</a>
<a target="_blank" rel="noopener noreferrer" href={sourceURLToSkillmapURL(badge.sourceURL)}>{pxt.U.rlf(badge.title)}</a>
)}</span>
}
}
Expand Down
6 changes: 1 addition & 5 deletions react-common/styles/profile/profile.css
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,6 @@
}


.profile-badge.disabled img {
filter: grayscale(1);
opacity: 0.5;
}

.profile-badge.disabled i.ui.icon {
line-height: 1;
vertical-align: middle;
Expand Down Expand Up @@ -280,6 +275,7 @@
margin-right: 0;
text-align: center;
color: var(--header-text-color);
overflow: hidden;
}

.profile-initials-portrait {
Expand Down
1 change: 1 addition & 0 deletions skillmap/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ module.exports = {
"parserOptions": {
"project": "skillmap/tsconfig.json",
},
"ignorePatterns": ["tests/**/*.spec.ts", "public/**/*", "build/**/*"]
}
22 changes: 10 additions & 12 deletions skillmap/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ interface AppState {
error?: string;
cloudSyncCheckHasFinished: boolean;
badgeSyncLock: boolean;
syncingLocalState?: boolean;
showingSyncLoader?: boolean;
}

class AppImpl extends React.Component<AppProps, AppState> {
Expand Down Expand Up @@ -235,9 +235,8 @@ class AppImpl extends React.Component<AppProps, AppState> {
protected async cloudSyncCheckAsync() {
const res = await this.ready();
if (!await authClient.loggedInAsync()) {
this.setState({cloudSyncCheckHasFinished: true, syncingLocalState: false});
this.setState({cloudSyncCheckHasFinished: true});
} else {
this.setState({syncingLocalState: true});
const doCloudSyncCheckAsync = async () => {
const state = store.getState();
const localUser = await getLocalUserStateAsync();
Expand Down Expand Up @@ -315,14 +314,14 @@ class AppImpl extends React.Component<AppProps, AppState> {
action: "requestprojectcloudstatus",
headerIds: getFlattenedHeaderIds(currentUser, state.pageSourceUrl)
} as pxt.editor.EditorMessageRequestProjectCloudStatus);
this.setState({cloudSyncCheckHasFinished: true, syncingLocalState: false});
this.setState({ cloudSyncCheckHasFinished: true, showingSyncLoader: false });
}
// Timeout if cloud sync check doesn't complete in a reasonable timeframe.
const TIMEOUT_MS = 10 * 1000;
await Promise.race([
pxt.U.delay(TIMEOUT_MS).then(() => {
if (!this.state.cloudSyncCheckHasFinished)
this.setState({cloudSyncCheckHasFinished: true, syncingLocalState: false});
this.setState({ cloudSyncCheckHasFinished: true, showingSyncLoader: false });
}),
doCloudSyncCheckAsync()]);
}
Expand All @@ -343,6 +342,10 @@ class AppImpl extends React.Component<AppProps, AppState> {
await this.initLocalizationAsync();
await this.parseHashAsync();
this.readyPromise.setAppMounted();

if (await authClient.loggedInAsync() && !this.state.cloudSyncCheckHasFinished) {
this.setState({ showingSyncLoader: true });
}
}

componentWillUnmount() {
Expand All @@ -354,11 +357,11 @@ class AppImpl extends React.Component<AppProps, AppState> {

render() {
const { skillMaps, activityOpen, backgroundImageUrl, theme } = this.props;
const { error, syncingLocalState } = this.state;
const { error, showingSyncLoader } = this.state;
const maps = Object.keys(skillMaps).map((id: string) => skillMaps[id]);
return (<div className={`app-container ${pxt.appTarget.id}`}>
<HeaderBar />
{syncingLocalState && <div className={"makecode-frame-loader"}>
{showingSyncLoader && <div className={"makecode-frame-loader"}>
<img src={resolvePath("assets/logo.svg")} alt={lf("MakeCode Logo")} />
<div className="makecode-frame-loader-text">{lf("Saving to cloud...")}</div>
</div>}
Expand Down Expand Up @@ -433,11 +436,6 @@ class AppImpl extends React.Component<AppProps, AppState> {
}
}

if ((!this.props.signedIn || (this.props.signedIn && this.state.cloudSyncCheckHasFinished))
&& this.state.syncingLocalState) {
this.setState({ syncingLocalState: false });
}

await this.syncBadgesAsync();
}

Expand Down
9 changes: 7 additions & 2 deletions skillmap/src/components/AppModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ export class AppModalImpl extends React.Component<AppModalProps, AppModalState>

return <Modal title={title} onClose={this.handleOnClose} actions={buttons}>
{lf("Use the button below to get your completion certificate!")}
{reward.previewUrl &&
<div className="certificate-reward">
<img src={reward.previewUrl} alt={lf("certificate Preview")} />
</div>
}
</Modal>
}

Expand All @@ -523,7 +528,7 @@ export class AppModalImpl extends React.Component<AppModalProps, AppModalState>
if (signedIn) {
message = jsxLF(
lf("You’ve received the {0} Badge! Find it in the badges section of your {1}."),
<span>{pxt.U.rlf(skillMap!.displayName)}</span>,
<span>{pxt.U.rlf(badge!.title)}</span>,
<a onClick={goToBadges}>{lf("User Profile")}</a>
);
buttons.push(
Expand Down Expand Up @@ -570,10 +575,10 @@ export class AppModalImpl extends React.Component<AppModalProps, AppModalState>


return <Modal title={title} onClose={this.handleOnClose} actions={buttons}>
{message}
<div className="badge-modal-image">
<Badge badge={badge!} />
</div>
{message}
</Modal>
}
}
Expand Down
2 changes: 2 additions & 0 deletions skillmap/src/lib/skillMap.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ type MapReward = MapRewardCertificate | MapCompletionBadge;
interface MapRewardCertificate {
type: "certificate";
url: string;
previewUrl?: string;
}

interface MapCompletionBadge {
type: "completion-badge";
imageUrl: string;
displayName?: string;
}

interface MapRewardNode extends BaseNode {
Expand Down
Loading

0 comments on commit 94051a7

Please sign in to comment.