Skip to content

Commit

Permalink
Merge branch 'main' into stage-2-experiments
Browse files Browse the repository at this point in the history
  • Loading branch information
andy1li authored Jan 6, 2025
2 parents 4f28dc3 + 3a8b1d6 commit 00873ab
Show file tree
Hide file tree
Showing 19 changed files with 490 additions and 251 deletions.
1 change: 1 addition & 0 deletions app/components/code-mirror.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
{{did-update this.optionDidChange "editable" @editable}}
{{did-update this.optionDidChange "foldGutter" @foldGutter}}
{{did-update this.optionDidChange "highlightActiveLine" @highlightActiveLine}}
{{did-update this.optionDidChange "highlightNewlines" @highlightNewlines}}
{{did-update this.optionDidChange "highlightSelectionMatches" @highlightSelectionMatches}}
{{did-update this.optionDidChange "highlightSpecialChars" @highlightSpecialChars}}
{{did-update this.optionDidChange "highlightTrailingWhitespace" @highlightTrailingWhitespace}}
Expand Down
6 changes: 6 additions & 0 deletions app/components/code-mirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
} from '@codemirror/language';
import { languages } from '@codemirror/language-data';
import { markdown } from '@codemirror/lang-markdown';
import { highlightNewlines } from 'codecrafters-frontend/utils/code-mirror-highlight-newlines';

function generateHTMLElement(src: string): HTMLElement {
const div = document.createElement('div');
Expand Down Expand Up @@ -65,6 +66,7 @@ const OPTION_HANDLERS: { [key: string]: OptionHandler } = {
dropCursor: ({ dropCursor: enabled }) => (enabled ? [dropCursor()] : []),
editable: ({ editable }) => [EditorView.editable.of(!!editable)],
highlightActiveLine: ({ highlightActiveLine: enabled }) => (enabled ? [highlightActiveLine(), highlightActiveLineGutter()] : []),
highlightNewlines: ({ highlightNewlines: enabled }) => (enabled ? [highlightNewlines()] : []),
highlightSelectionMatches: ({ highlightSelectionMatches: enabled }) => (enabled ? [highlightSelectionMatches()] : []),
highlightSpecialChars: ({ highlightSpecialChars: enabled }) => (enabled ? [highlightSpecialChars()] : []),
highlightTrailingWhitespace: ({ highlightTrailingWhitespace: enabled }) => (enabled ? [highlightTrailingWhitespace()] : []),
Expand Down Expand Up @@ -228,6 +230,10 @@ export interface Signature {
* Enable inline highlighting of changes in the diff
*/
highlightChanges?: boolean;
/**
* Enable highlighting of new line symbols
*/
highlightNewlines?: boolean;
/**
* Enable highlighting of current selection matches in the document
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import Store from '@ember-data/store';
import type CourseStageModel from 'codecrafters-frontend/models/course-stage';
import type RepositoryModel from 'codecrafters-frontend/models/repository';
import type { Step } from 'codecrafters-frontend/components/expandable-step-list';
import type CourseStageStep from 'codecrafters-frontend/utils/course-page-step-list/course-stage-step';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';

interface Signature {
Element: HTMLDivElement;

Args: {
repository: RepositoryModel;
courseStage: CourseStageModel;
currentStep: CourseStageStep;
};
}

Expand Down Expand Up @@ -70,6 +73,10 @@ export default class FirstStageTutorialCardComponent extends Component<Signature
@service declare featureFlags: FeatureFlagsService;
@service declare store: Store;

get hasPassedTests() {
return this.args.currentStep.testsStatus === 'passed' || this.args.currentStep.status === 'complete';
}

get navigateToFileStepIsComplete() {
return this.navigateToFileStepWasMarkedAsComplete || this.uncommentCodeStepIsComplete;
}
Expand Down
2 changes: 1 addition & 1 deletion app/components/track-page/start-track-button.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<PrimaryButton class="mr-2 flex items-center" data-test-start-track-button {{on "click" this.handleClicked}} @size="large" ...attributes>
<PrimaryButton class="mr-2 flex items-center" data-test-primary-start-track-button {{on "click" this.handleClicked}} @size="large" ...attributes>
{{#if this.currentUserIsAnonymous}}
{{svg-jar "github" class="fill-current w-5 transform transition-all mr-2"}}
{{/if}}
Expand Down
2 changes: 1 addition & 1 deletion app/components/track-page/start-track-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class CourseOverviewStartTrackButtonComponent extends Component<S
if (this.currentUserIsAnonymous) {
this.authenticator.initiateLogin(null);
} else {
this.router.transitionTo('course', this.args.courses[0]!.slug, { queryParams: { track: this.args.language.slug } });
this.router.transitionTo('course', this.args.courses[0]!.slug, { queryParams: { repo: null, track: this.args.language.slug } });
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions app/controllers/course/stage/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export default class CourseStageInstructionsController extends Controller {
});
}

get currentCourse() {
return this.model.courseStage.course;
}

get currentStep(): CourseStageStep {
return this.coursePageState.currentStep as CourseStageStep;
}
Expand All @@ -55,6 +59,10 @@ export default class CourseStageInstructionsController extends Controller {
return !!this.prerequisiteInstructionsMarkdown;
}

get shouldShowStage1ForumLinkCTA() {
return this.model.courseStage.isFirst && this.currentStep.testsStatus !== 'passed' && this.currentStep.status !== 'complete';
}

get shouldShowTestRunnerCard() {
return this.isCurrentStage && this.currentStep.status !== 'complete';
}
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/demo/code-mirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const OPTION_DEFAULTS = {
foldGutter: true,
highlightActiveLine: true,
highlightChanges: false,
highlightNewlines: false,
highlightSelectionMatches: true,
highlightSpecialChars: true,
highlightTrailingWhitespace: true,
Expand Down Expand Up @@ -97,6 +98,7 @@ export default class DemoCodeMirrorController extends Controller {
'foldGutter',
'highlightActiveLine',
'highlightChanges',
'highlightNewlines',
'highlightSelectionMatches',
'highlightSpecialChars',
'highlightTrailingWhitespace',
Expand Down Expand Up @@ -147,6 +149,7 @@ export default class DemoCodeMirrorController extends Controller {
@tracked foldGutter = OPTION_DEFAULTS.foldGutter;
@tracked highlightActiveLine = OPTION_DEFAULTS.highlightActiveLine;
@tracked highlightChanges = OPTION_DEFAULTS.highlightChanges;
@tracked highlightNewlines = OPTION_DEFAULTS.highlightNewlines;
@tracked highlightSelectionMatches = OPTION_DEFAULTS.highlightSelectionMatches;
@tracked highlightSpecialChars = OPTION_DEFAULTS.highlightSpecialChars;
@tracked highlightTrailingWhitespace = OPTION_DEFAULTS.highlightTrailingWhitespace;
Expand Down
1 change: 1 addition & 0 deletions app/routes/demo/code-mirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const QUERY_PARAMS = [
'foldGutter',
'highlightActiveLine',
'highlightChanges',
'highlightNewlines',
'highlightSelectionMatches',
'highlightSpecialChars',
'highlightTrailingWhitespace',
Expand Down
33 changes: 29 additions & 4 deletions app/templates/course/stage/instructions.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@
{{/if}}

{{#if @model.courseStage.isFirst}}
<CoursePage::CourseStageStep::FirstStageTutorialCard @repository={{@model.activeRepository}} @courseStage={{@model.courseStage}} class="mb-6" />
<CoursePage::CourseStageStep::FirstStageTutorialCard
@repository={{@model.activeRepository}}
@courseStage={{@model.courseStage}}
@currentStep={{this.currentStep}}
class="mb-6"
/>
{{/if}}

{{#if @model.courseStage.isSecond}}
Expand Down Expand Up @@ -78,7 +83,27 @@
</div>
{{/if}}

{{! TODO: Remove this temporary card }}
{{#if this.shouldShowStage1ForumLinkCTA}}
<div class="prose dark:prose-invert prose-sm prose-compact ml-4 mb-10">
<p>
Need help?
<a
href="https://forum.codecrafters.io/new-topic?category=Challenges&tags=challenge%3A{{this.currentCourse.slug}}&title=%5B{{this.currentCourse.shortName}}%5D%20How%20to%20pass%20the%20first%20stage%3F&body=Checklist%3A%0A%0A1.%20%E2%9C%85%20or%20%E2%9D%8C%3A%20I%27ve%20uncommented%20the%20code.%0A2.%20%E2%9C%85%20or%20%E2%9D%8C%3A%20I%27ve%20saved%20the%20changes.%0A3.%20%E2%9C%85%20or%20%E2%9D%8C%3A%20I%27ve%20run%20the%20git%20commands%3A%0A%0A%60%60%60%0Agit%20commit%20-am%20%22%5Bseeking%20help%20on%20forum%5D%22%0Agit%20push%20origin%20master%0A%60%60%60%0A%0A---%0A%0AHere%E2%80%99s%20a%20screenshot%20showing%20the%20output%20from%20running%20the%20Git%20commands%3A%0A%0A%5BAttach%20screenshot%20here%5D%0A%0A%5BShare%20other%20details%20here%5D"
target="_blank"
rel="noopener noreferrer"
>
Post your issue</a>
on the forum —
<img
alt="avatar"
src="https://avatars.githubusercontent.com/u/1450947"
class="inline-block ml-1 mr-1.5 my-0 -translate-y-px overflow-hidden rounded-full size-4 filter drop-shadow-sm ring-1 ring-white dark:ring-white/5 shadow"
/>Andy usually replies within 6 hours.
</p>
</div>
{{/if}}

{{! TODO: Remove this temporary CTA }}
{{#if (and @model.courseStage.isSecond (eq @model.courseStage.course.slug "shell"))}}
<div class="my-10 mx-6 flex items-start gap-4">
<img
Expand All @@ -87,9 +112,9 @@
class="shrink-0 overflow-hidden rounded-full size-8 filter drop-shadow-sm ring-1 ring-white dark:ring-white/5 shadow"
/>
<div class="prose prose-compact dark:prose-invert text-sm">
<h4 class="text-base text-gray-600 dark:text-gray-300">Hi there! I'm Andy 👋</h4>
<h4 class="text-base text-gray-600 dark:text-gray-300">Help us improve!</h4>
<p>
I'm working on improving our stage 2 experience.
Hi there! I'm Andy, and I'm working on improving the stage 2 experience.
</p>
<p>
If you find anything confusing here, mind letting me know on
Expand Down
5 changes: 5 additions & 0 deletions app/templates/demo/code-mirror.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@
<Input @type="checkbox" @checked={{this.highlightTrailingWhitespace}} />
<span class="ml-2">highlightTrailingWhitespace</span>
</label>
<label class="{{labelClasses}}" title="Enable highlighting of new line symbols">
<Input @type="checkbox" @checked={{this.highlightNewlines}} />
<span class="ml-2">highlightNewlines</span>
</label>
<label class="{{labelClasses}}" title="Enable inline highlighting of changes in the diff">
<Input @type="checkbox" @checked={{this.highlightChanges}} disabled={{not this.originalDocument}} />
<span class="ml-2 {{unless this.originalDocument 'text-gray-300'}}">highlightChanges</span>
Expand Down Expand Up @@ -328,6 +332,7 @@
@foldGutter={{this.foldGutter}}
@highlightActiveLine={{this.highlightActiveLine}}
@highlightChanges={{this.highlightChanges}}
@highlightNewlines={{this.highlightNewlines}}
@highlightSelectionMatches={{this.highlightSelectionMatches}}
@highlightSpecialChars={{this.highlightSpecialChars}}
@highlightTrailingWhitespace={{this.highlightTrailingWhitespace}}
Expand Down
4 changes: 2 additions & 2 deletions app/templates/pay.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@
@regionalDiscount={{if this.shouldApplyRegionalDiscount @model.regionalDiscount}}
@shouldShowAmortizedMonthlyPrice={{false}}
@title="Lifetime access"
@temporaryNoticeText="Price increases on Jan 1"
@temporaryNoticeTooltipText="The price for the lifetime plan will increase from $990 to $1,490 on January 1, 2025."
@temporaryNoticeText="Price increases on Jan 15"
@temporaryNoticeTooltipText="The price for the lifetime plan will increase from $990 to $1,490 on January 15, 2025."
data-test-lifetime-pricing-card
/>
</div>
Expand Down
84 changes: 84 additions & 0 deletions app/utils/code-mirror-highlight-newlines.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { Line } from '@codemirror/state';
import type { DecorationSet, ViewUpdate } from '@codemirror/view';
import { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';

class NewlineWidget extends WidgetType {
line: Line;
markerSymbol: string;

constructor({ line, markerSymbol = '↵' }: { line: Line; markerSymbol?: string }) {
super();
this.line = line;
this.markerSymbol = markerSymbol;
}

toDOM() {
const span = document.createElement('span');

span.textContent = this.markerSymbol;

span.className = 'cm-newline';

if (this.line.length === 0) {
span.className += ' cm-newline-empty';
}

return span;
}
}

const baseTheme = EditorView.baseTheme({
'.cm-newline': {
color: 'currentColor',
pointerEvents: 'none',
opacity: '0.5',
'&:not(.cm-newline-empty)': {
paddingLeft: '3px',
},
},
});

function highlightNewlines() {
return [
ViewPlugin.fromClass(
class {
decorations: DecorationSet;
constructor(view: EditorView) {
this.decorations = this.getDecorations(view);
}

getDecorations(view: EditorView) {
const widgets = [];

for (const { from, to } of view.visibleRanges) {
for (let pos = from; pos <= to; ) {
const line = view.state.doc.lineAt(pos);

if (line.length === 0) {
widgets.push(Decoration.widget({ widget: new NewlineWidget({ line }), side: 1 }).range(pos));
} else {
widgets.push(Decoration.widget({ widget: new NewlineWidget({ line }), side: 1 }).range(line.to));
}

pos = line.to + 1;
}
}

return Decoration.set(widgets, true);
}

update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
this.decorations = this.getDecorations(update.view);
}
}
},
{
decorations: (v) => v.decorations,
},
),
baseTheme,
];
}

export { highlightNewlines };
4 changes: 4 additions & 0 deletions app/utils/parse-diff-as-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ export default function parseDiffAsDocument(diff: string = '') {
const original = [];

for (const line of diffLines) {
if (line === '\\ No newline at end of file') {
continue;
}

if (line.startsWith('-')) {
original.push(line.substring(1));
} else if (line.startsWith('+')) {
Expand Down
Loading

0 comments on commit 00873ab

Please sign in to comment.