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
2 changes: 1 addition & 1 deletion localtypings/pxteditor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ declare namespace pxt.editor {
forceUpdate(): void;

reloadEditor(): void;
openBlocks(): void;
openBlocks(showKeyboardControlsHint?: boolean): void;
openJavaScript(giveFocusOnLoading?: boolean): void;
openPython(giveFocusOnLoading?: boolean): void;
openAssets(): void;
Expand Down
2 changes: 1 addition & 1 deletion pxtlib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ namespace pxt.auth {
export const DEFAULT_USER_PREFERENCES: () => UserPreferences = () => ({
language: pxt.appTarget.appTheme.defaultLocale,
highContrast: false,
accessibleBlocks: false,
accessibleBlocks: undefined, // Defaulted at read time depending on flag
colorThemeIds: {}, // Will lookup pxt.appTarget.appTheme.defaultColorTheme for active target
reader: "",
skillmap: { mapProgress: {}, completedTags: {} },
Expand Down
3 changes: 2 additions & 1 deletion webapp/src/accessibility.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import * as React from "react";
import * as auth from "./auth";
import * as core from "./core";
import * as data from "./data";
import * as sui from "./sui";

Expand Down Expand Up @@ -34,7 +35,7 @@ export class EditorAccessibilityMenu extends data.Component<EditorAccessibilityM
}

openBlocks(e: React.MouseEvent<HTMLElement>) {
this.props.parent.openBlocks();
this.props.parent.openBlocks(core.isKeyboardControlsByDefault());
}

openJavaScript() {
Expand Down
6 changes: 5 additions & 1 deletion webapp/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -716,9 +716,13 @@ export class ProjectView
pxt.shell.setEditorLanguagePref("js");
}

openBlocks() {
openBlocks(showKeyboardControlsHint?: boolean) {
if (this.updatingEditorFile) return; // already transitioning

if (showKeyboardControlsHint) {
this.blocksEditor.pendingKeyboardControlsHint = true;
}
Comment thread
abchatra marked this conversation as resolved.

if (this.isBlocksActive()) {
if (this.state.embedSimView) this.setState({ embedSimView: false });
// This timeout prevents key events from being handled by Blockly's keyboard
Expand Down
9 changes: 7 additions & 2 deletions webapp/src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ class AuthClient extends pxt.auth.AuthClient {
// Identity not available, read from local storage
switch (path) {
case HIGHCONTRAST: return /^true$/i.test(pxt.storage.getLocal(HIGHCONTRAST));
case ACCESSIBLE_BLOCKS: return /^true$/i.test(pxt.storage.getLocal(ACCESSIBLE_BLOCKS));
case ACCESSIBLE_BLOCKS: {
const stored = pxt.storage.getLocal(ACCESSIBLE_BLOCKS);
if (stored == null) return core.isKeyboardControlsByDefault();
return /^true$/i.test(stored);
}
case COLOR_THEME_IDS: return pxt.U.jsonTryParse(pxt.storage.getLocal(COLOR_THEME_IDS)) as pxt.auth.ColorThemeIdsState;
case LANGUAGE: return pxt.storage.getLocal(LANGUAGE);
case READER: return pxt.storage.getLocal(READER);
Expand All @@ -134,7 +138,7 @@ class AuthClient extends pxt.auth.AuthClient {
switch (field) {
case FIELD_USER_PREFERENCES: return { ...state.preferences };
case FIELD_HIGHCONTRAST: return state.preferences?.highContrast ?? pxt.auth.DEFAULT_USER_PREFERENCES().highContrast;
case FIELD_KEYBOARD_CONTROLS: return state.preferences?.accessibleBlocks ?? pxt.auth.DEFAULT_USER_PREFERENCES().accessibleBlocks;
case FIELD_KEYBOARD_CONTROLS: return state.preferences?.accessibleBlocks ?? core.isKeyboardControlsByDefault();
case FIELD_COLOR_THEME_IDS: return state.preferences?.colorThemeIds ?? pxt.auth.DEFAULT_USER_PREFERENCES().colorThemeIds;
case FIELD_LANGUAGE: return state.preferences?.language ?? pxt.auth.DEFAULT_USER_PREFERENCES().language;
case FIELD_READER: return state.preferences?.reader ?? pxt.auth.DEFAULT_USER_PREFERENCES().reader;
Expand Down Expand Up @@ -250,6 +254,7 @@ export async function setAccessibleBlocksPrefAsync(accessibleBlocks: boolean, ev
"auth.setAccessibleBlocks",
{
enabling: accessibleBlocks ? "true" : "false",
defaultOn: core.isKeyboardControlsByDefault() ? "true" : "false",
eventSource: eventSource,
local: !cli ? "true" : "false"
}
Expand Down
13 changes: 13 additions & 0 deletions webapp/src/blocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class Editor extends toolboxeditor.ToolboxEditor {
loadingXmlPromise: Promise<any>;
compilationResult: pxtblockly.BlockCompilationResult;
shouldFocusWorkspace = false;
pendingKeyboardControlsHint = false;
functionsDialog: CreateFunctionDialog = null;

showCategories: boolean = true;
Expand Down Expand Up @@ -997,9 +998,21 @@ export class Editor extends toolboxeditor.ToolboxEditor {
if (accessibleBlocksEnabled) {
(this.editor.getSvgGroup() as SVGElement).focus();
Blockly.hideChaff();

if (this.pendingKeyboardControlsHint) {
this.pendingKeyboardControlsHint = false;
this.showKeyboardControlsHint();
}
}
}

showKeyboardControlsHint() {
if (!this.editor || !Blockly.Msg["HELP_PROMPT"]) return;
const shortcut = pxt.BrowserUtils.isMac() ? "⌘ /" : lf("Ctrl") + " + /";
const message = Blockly.Msg["HELP_PROMPT"].replace("%1", shortcut);
Blockly.Toast.show(this.editor, { message, id: "helpHint", oncePerSession: true });
}

hasUndo() {
const undoStack = this.editor?.getUndoStack();
const redoStack = this.editor?.getRedoStack();
Expand Down
7 changes: 7 additions & 0 deletions webapp/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,13 @@ export function getHighContrastOnce(): boolean {
return ThemeManager.isCurrentThemeHighContrast();
}

/**
* Returns true if keyboard controls should be enabled by default.
*/
export function isKeyboardControlsByDefault(): boolean {
return /keyboardcontrols=1/i.test(window.location.href);
}

export async function toggleAccessibleBlocks(eventSource: string) {
await setAccessibleBlocks(!data.getData<boolean>(auth.ACCESSIBLE_BLOCKS), eventSource);
}
Expand Down
Loading