share dialog is back
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
import { HTMLTemplateResult, html, css, CSSResultGroup } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "../components";
|
||||
import "./nav.ts";
|
||||
import "./nav";
|
||||
import "./share";
|
||||
import { ShareSessionDialog } from "./share";
|
||||
|
||||
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
|
||||
|
||||
// Set the base path to the folder you copied Shoelace's assets to
|
||||
setBasePath('/shoelace');
|
||||
|
||||
import "@shoelace-style/shoelace/dist/components/split-panel/split-panel.js";
|
||||
|
||||
@@ -29,9 +36,9 @@ export class App extends BaseElement {
|
||||
flex-grow: 1;
|
||||
// z-index: auto;
|
||||
}
|
||||
.z-fix {
|
||||
z-index: 900;
|
||||
}
|
||||
// .z-fix {
|
||||
// z-index: 900;
|
||||
// }
|
||||
sl-split-panel {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -40,9 +47,12 @@ export class App extends BaseElement {
|
||||
|
||||
editorSettings: { fontSize: number; relativeLineNumbers: boolean };
|
||||
|
||||
get editor() {
|
||||
return this.renderRoot.querySelector("ace-ic10") as IC10Editor;
|
||||
}
|
||||
@query('ace-ic10') accessor editor: IC10Editor;
|
||||
@query('session-share-dialog') accessor shareDialog: ShareSessionDialog;
|
||||
|
||||
// get editor() {
|
||||
// return this.renderRoot.querySelector("ace-ic10") as IC10Editor;
|
||||
// }
|
||||
|
||||
vm!: VirtualMachine;
|
||||
session!: Session;
|
||||
@@ -57,16 +67,16 @@ export class App extends BaseElement {
|
||||
|
||||
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
||||
const root = super.createRenderRoot();
|
||||
root.addEventListener('app-share-session', this._handleShare);
|
||||
root.addEventListener('app-open-file', this._handleOpenFile);
|
||||
root.addEventListener('app-save-as', this._handleSaveAs);
|
||||
root.addEventListener('app-share-session', this._handleShare.bind(this));
|
||||
root.addEventListener('app-open-file', this._handleOpenFile.bind(this));
|
||||
root.addEventListener('app-save-as', this._handleSaveAs.bind(this));
|
||||
return root;
|
||||
}
|
||||
|
||||
protected render(): HTMLTemplateResult {
|
||||
return html`
|
||||
<div class="app-container">
|
||||
<app-nav class="z-fix"></app-nav>
|
||||
<app-nav></app-nav>
|
||||
<div class="app-body">
|
||||
<sl-split-panel
|
||||
style="--min: 20em; --max: calc(100% - 20em);"
|
||||
@@ -74,10 +84,11 @@ export class App extends BaseElement {
|
||||
snap="512px 50%"
|
||||
snap-threshold="15"
|
||||
>
|
||||
<ace-ic10 slot="start"></ace-ic10>
|
||||
<ace-ic10 slot="start" style=""></ace-ic10>
|
||||
<div slot="end">Controls</div>
|
||||
</sl-split-panel>
|
||||
</div>
|
||||
<session-share-dialog></session-share-dialog>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -87,6 +98,8 @@ export class App extends BaseElement {
|
||||
|
||||
_handleShare(_e: Event) {
|
||||
// TODO:
|
||||
this.shareDialog.link = window.location.href;
|
||||
this.shareDialog.show();
|
||||
}
|
||||
|
||||
_handleSaveAs(_e: Event) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { App } from "./app";
|
||||
import { Nav } from "./nav";
|
||||
import { ShareSessionDialog } from "./share";
|
||||
import "./icons";
|
||||
export { App, Nav }
|
||||
export { App, Nav, ShareSessionDialog }
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { HTMLTemplateResult, html, css } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "../components";
|
||||
|
||||
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
|
||||
import "@shoelace-style/shoelace/dist/components/icon-button/icon-button.js";
|
||||
import "@shoelace-style/shoelace/dist/components/menu/menu.js";
|
||||
import "@shoelace-style/shoelace/dist/components/divider/divider.js";
|
||||
@@ -79,6 +81,7 @@ export class Nav extends BaseElement {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 100;
|
||||
}
|
||||
nav {
|
||||
border-bottom: 1px solid rgb(108, 117, 125);
|
||||
@@ -101,7 +104,7 @@ export class Nav extends BaseElement {
|
||||
label="Main Menu"
|
||||
></sl-icon-button>
|
||||
|
||||
<sl-menu class="menu" @sl-select=${this._menuClickHandler}>
|
||||
<sl-menu class="menu" @sl-select=${this._menuClickHandler} style="z-index: 10">
|
||||
<sl-menu-item value="share">Share</sl-menu-item>
|
||||
<sl-menu-item value="openFile">Open File</sl-menu-item>
|
||||
<sl-menu-item value="saveAs">Save As</sl-menu-item>
|
||||
@@ -180,10 +183,10 @@ export class Nav extends BaseElement {
|
||||
this.dispatchEvent(new CustomEvent("app-save-as", { bubbles: true }));
|
||||
break;
|
||||
case "editorSettings":
|
||||
window.Editor?.settingDialog.show();
|
||||
window.Editor.settingDialog.show();
|
||||
break;
|
||||
case "keyboardShortcuts":
|
||||
// TODO: bind
|
||||
window.Editor.kbShortcuts.show();
|
||||
break;
|
||||
default:
|
||||
console.log("Unknown main menu item", item.value);
|
||||
|
||||
49
www/src/js/app/share.ts
Normal file
49
www/src/js/app/share.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { HTMLTemplateResult, html, css } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "../components";
|
||||
|
||||
import "@shoelace-style/shoelace/dist/components/dialog/dialog.js";
|
||||
import "@shoelace-style/shoelace/dist/components/input/input.js";
|
||||
import "@shoelace-style/shoelace/dist/components/icon/icon.js";
|
||||
import "@shoelace-style/shoelace/dist/components/icon-button/icon-button.js";
|
||||
import "@shoelace-style/shoelace/dist/components/copy-button/copy-button.js";
|
||||
import SlDialog from "@shoelace-style/shoelace/dist/components/dialog/dialog.js";
|
||||
import SlInput from "@shoelace-style/shoelace/dist/components/input/input.js";
|
||||
|
||||
@customElement("session-share-dialog")
|
||||
export class ShareSessionDialog extends BaseElement {
|
||||
@query(".dialog") accessor dialog: SlDialog;
|
||||
@query(".input") accessor input: SlInput;
|
||||
@property({ type: String }) accessor link: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<sl-dialog label="Share This Code" class="dialog" style="--header-spacing: 0.75em;">
|
||||
<sl-input class="input" id="session-link-input" value="${this.link}">
|
||||
<sl-icon name="link-45deg" slot="prefix"></sl-icon>
|
||||
<sl-copy-button from="session-link-input.value" slot="suffix">
|
||||
<sl-icon slot="copy-icon" name="clipboard"></sl-icon>
|
||||
<sl-icon slot="success-icon" name="clipboard-check"></sl-icon>
|
||||
<sl-icon slot="error-icon" name="clipboard-x"></sl-icon>
|
||||
</sl-copy-button>
|
||||
</sl-input>
|
||||
</sl-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
show() {
|
||||
this.dialog.show();
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.dialog.hide();
|
||||
}
|
||||
|
||||
_handleCopyClick() {
|
||||
this.input.value;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ export async function setupLspWorker() {
|
||||
}
|
||||
|
||||
export import EditSession = ace.Ace.EditSession;
|
||||
export import Editor = ace.Ace.Editor;
|
||||
import { Range } from "ace-builds";
|
||||
|
||||
export { ace, TextMode, Range, AceLanguageClient }
|
||||
|
||||
@@ -4,7 +4,6 @@ import { rules as highlightRules } from "./ic10_highlight_rules";
|
||||
//Support function to create Ace mode
|
||||
function createAceMode(modeName: string, highlighterObj: ace.Ace.HighlightRulesMap) {
|
||||
(ace as any).define(modeName, ["require", "exports", "module"], function (require: any, exports: any, module: any) {
|
||||
console.log(require);
|
||||
var oop = require("ace/lib/oop");
|
||||
var TextMode = require("ace/mode/text").Mode;
|
||||
var TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
ace,
|
||||
Editor,
|
||||
EditSession,
|
||||
Range,
|
||||
AceLanguageClient,
|
||||
@@ -14,7 +15,7 @@ import "@shoelace-style/shoelace/dist/components/button/button.js";
|
||||
import "@shoelace-style/shoelace/dist/components/input/input.js";
|
||||
import "@shoelace-style/shoelace/dist/components/radio-button/radio-button.js";
|
||||
import "@shoelace-style/shoelace/dist/components/radio-group/radio-group.js";
|
||||
import '@shoelace-style/shoelace/dist/components/switch/switch.js';
|
||||
import "@shoelace-style/shoelace/dist/components/switch/switch.js";
|
||||
import SlDialog from "@shoelace-style/shoelace/dist/components/dialog/dialog.js";
|
||||
import SlRadioGroup from "@shoelace-style/shoelace/dist/components/radio-group/radio-group.js";
|
||||
import SlInput from "@shoelace-style/shoelace/dist/components/input/input.js";
|
||||
@@ -28,8 +29,11 @@ declare global {
|
||||
|
||||
import { BaseElement, defaultCss } from "../components";
|
||||
import { html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { Ref, createRef, ref } from "lit/directives/ref.js";
|
||||
import { customElement, property, query } from "lit/decorators.js";
|
||||
import { editorStyles } from "./styles";
|
||||
import "./shortcuts-ui";
|
||||
import { AceKeyboardShortcuts } from "./shortcuts-ui";
|
||||
|
||||
@customElement("ace-ic10")
|
||||
export class IC10Editor extends BaseElement {
|
||||
@@ -55,7 +59,7 @@ export class IC10Editor extends BaseElement {
|
||||
editorDiv: HTMLElement;
|
||||
editorContainerDiv: HTMLElement;
|
||||
editorStatusbarDiv: HTMLElement;
|
||||
editor: ace.Ace.Editor;
|
||||
editor: Editor;
|
||||
statusBar: any;
|
||||
snippetManager: any;
|
||||
observer: ResizeObserver;
|
||||
@@ -67,9 +71,9 @@ export class IC10Editor extends BaseElement {
|
||||
stylesAdded: string[];
|
||||
tooltipObserver: MutationObserver;
|
||||
|
||||
get settingDialog() {
|
||||
return this.shadowRoot?.querySelector('sl-dialog') as SlDialog
|
||||
}
|
||||
@query('.e-kb-shortcuts') accessor kbShortcuts: AceKeyboardShortcuts;
|
||||
|
||||
@query('.e-settings-dialog') accessor settingDialog: SlDialog;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -95,32 +99,53 @@ export class IC10Editor extends BaseElement {
|
||||
const result = html`
|
||||
<div
|
||||
id="editorContainer"
|
||||
style="height: 100%; width: 100%; position: relative;"
|
||||
style="height: 100%; width: 100%; position: relative; z-index: auto;"
|
||||
>
|
||||
<div
|
||||
id="editor"
|
||||
style="position: absolute; top: 0; right: 0; bottom: 0; left: 0;"
|
||||
<!-- style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 0; isolation: isolate;" -->
|
||||
></div>
|
||||
<div id="editorStatusbar"></div>
|
||||
</div>
|
||||
<sl-dialog label="Editor Settings" class="dialog-focus">
|
||||
<sl-radio-group id="editorKeyboardRadio" label="Editor Keyboard Bindings" value=${this.settings.keyboard}>
|
||||
<sl-dialog
|
||||
label="Editor Settings"
|
||||
class="dialog-focus e-settings-dialog"
|
||||
>
|
||||
<sl-radio-group
|
||||
id="editorKeyboardRadio"
|
||||
label="Editor Keyboard Bindings"
|
||||
value=${this.settings.keyboard}
|
||||
>
|
||||
<sl-radio-button value="ace">Ace</sl-radio-button>
|
||||
<sl-radio-button value="vim">Vim</sl-radio-button>
|
||||
<sl-radio-button value="emacs">Emacs</sl-radio-button>
|
||||
<sl-radio-button value="sublime">Sublime</sl-radio-button>
|
||||
<sl-radio-button value="vscode">VS Code</sl-radio-button>
|
||||
</sl-radio-group>
|
||||
<sl-radio-group id="editorCursorRadio" label="Editor Cursor Style" value=${this.settings.cursor}>
|
||||
<sl-radio-group
|
||||
id="editorCursorRadio"
|
||||
label="Editor Cursor Style"
|
||||
value=${this.settings.cursor}
|
||||
>
|
||||
<sl-radio-button value="ace">Ace</sl-radio-button>
|
||||
<sl-radio-button value="slim">Slim</sl-radio-button>
|
||||
<sl-radio-button value="smooth">Smooth</sl-radio-button>
|
||||
<sl-radio-button value="smooth slim">Smooth And Slim</sl-radio-button>
|
||||
<sl-radio-button value="wide">Wide</sl-radio-button>
|
||||
</sl-radio-group>
|
||||
<sl-input id="editorFontSize" label="Font Size" type="number" value="${this.settings.fontSize}"></sl-input>
|
||||
<sl-switch id="editorRelativeLineNumbers" ?checked=${this.settings.relativeLineNumbers}>Relative Line Numbers</sl-switch>
|
||||
<sl-input
|
||||
id="editorFontSize"
|
||||
label="Font Size"
|
||||
type="number"
|
||||
value="${this.settings.fontSize}"
|
||||
></sl-input>
|
||||
<sl-switch
|
||||
id="editorRelativeLineNumbers"
|
||||
?checked=${this.settings.relativeLineNumbers}
|
||||
>Relative Line Numbers</sl-switch
|
||||
>
|
||||
</sl-dialog>
|
||||
<ace-kb-menu class="e-kb-shortcuts"></ace-kb-menu>
|
||||
`;
|
||||
return result;
|
||||
}
|
||||
@@ -242,6 +267,8 @@ export class IC10Editor extends BaseElement {
|
||||
});
|
||||
|
||||
this.observer.observe(this.editorContainerDiv);
|
||||
this.kbShortcuts.editor = this.editor;
|
||||
this.kbShortcuts.requestUpdate();
|
||||
|
||||
this.initializeEditor();
|
||||
}
|
||||
@@ -324,37 +351,57 @@ export class IC10Editor extends BaseElement {
|
||||
this.shadowRoot!.querySelector(".ace_scrollbar-h")!,
|
||||
);
|
||||
|
||||
editor.commands.addCommands([{
|
||||
name: "showSettingsMenu",
|
||||
// description: "Show settings menu",
|
||||
bindKey: { win: "Ctrl-,", mac: "Command-,"},
|
||||
exec: (_editor: ace.Ace.Editor) => {
|
||||
that.settingDialog.show();
|
||||
editor.commands.addCommands([
|
||||
{
|
||||
name: "showSettingsMenu",
|
||||
// description: "Show settings menu",
|
||||
bindKey: { win: "Ctrl-,", mac: "Command-," },
|
||||
exec: (_editor: Editor) => {
|
||||
that.settingDialog.show();
|
||||
},
|
||||
},
|
||||
}]);
|
||||
{
|
||||
name: "showKeyboardShortcuts",
|
||||
bindKey: {
|
||||
win: "Ctrl-Alt-h",
|
||||
mac: "Command-Alt-h",
|
||||
},
|
||||
exec: (_editor: Editor) => {
|
||||
that.kbShortcuts.show();
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
this.updateEditorSettings();
|
||||
const keyboardRadio = this.renderRoot.querySelector("#editorKeyboardRadio")! as SlRadioGroup;
|
||||
const cursorRadio = this.renderRoot.querySelector("#editorCursorRadio")! as SlRadioGroup;
|
||||
const fontSize = this.renderRoot.querySelector("#editorFontSize")! as SlInput;
|
||||
const relativeLineNumbers = this.renderRoot.querySelector("#editorRelativeLineNumbers")! as SlSwitch;
|
||||
const keyboardRadio = this.renderRoot.querySelector(
|
||||
"#editorKeyboardRadio",
|
||||
)! as SlRadioGroup;
|
||||
const cursorRadio = this.renderRoot.querySelector(
|
||||
"#editorCursorRadio",
|
||||
)! as SlRadioGroup;
|
||||
const fontSize = this.renderRoot.querySelector(
|
||||
"#editorFontSize",
|
||||
)! as SlInput;
|
||||
const relativeLineNumbers = this.renderRoot.querySelector(
|
||||
"#editorRelativeLineNumbers",
|
||||
)! as SlSwitch;
|
||||
|
||||
keyboardRadio.addEventListener("sl-change", _e => {
|
||||
keyboardRadio.addEventListener("sl-change", (_e) => {
|
||||
that.settings.keyboard = keyboardRadio.value;
|
||||
that.updateEditorSettings();
|
||||
that.saveEditorSettings();
|
||||
});
|
||||
cursorRadio?.addEventListener("sl-change", _e => {
|
||||
cursorRadio?.addEventListener("sl-change", (_e) => {
|
||||
that.settings.cursor = cursorRadio.value;
|
||||
that.updateEditorSettings();
|
||||
that.saveEditorSettings();
|
||||
});
|
||||
fontSize?.addEventListener("sl-change", _e => {
|
||||
that.settings.fontSize = parseInt(fontSize.value)
|
||||
fontSize?.addEventListener("sl-change", (_e) => {
|
||||
that.settings.fontSize = parseInt(fontSize.value);
|
||||
that.updateEditorSettings();
|
||||
that.saveEditorSettings();
|
||||
});
|
||||
relativeLineNumbers?.addEventListener("sl-change", _e => {
|
||||
relativeLineNumbers?.addEventListener("sl-change", (_e) => {
|
||||
that.settings.relativeLineNumbers = relativeLineNumbers.checked;
|
||||
that.updateEditorSettings();
|
||||
that.saveEditorSettings();
|
||||
@@ -505,14 +552,20 @@ export class IC10Editor extends BaseElement {
|
||||
}
|
||||
|
||||
updateEditorSettings() {
|
||||
if (this.settings.keyboard === 'ace') {
|
||||
this.editor.setOption('keyboardHandler', null);
|
||||
if (this.settings.keyboard === "ace") {
|
||||
this.editor.setOption("keyboardHandler", null);
|
||||
} else {
|
||||
this.editor.setOption('keyboardHandler', `ace/keyboard/${this.settings.keyboard}`);
|
||||
this.editor.setOption(
|
||||
"keyboardHandler",
|
||||
`ace/keyboard/${this.settings.keyboard}`,
|
||||
);
|
||||
}
|
||||
this.editor.setOption('cursorStyle', this.settings.cursor as any);
|
||||
this.editor.setOption('fontSize', this.settings.fontSize);
|
||||
this.editor.setOption('relativeLineNumbers', this.settings.relativeLineNumbers);
|
||||
this.editor.setOption("cursorStyle", this.settings.cursor as any);
|
||||
this.editor.setOption("fontSize", this.settings.fontSize);
|
||||
this.editor.setOption(
|
||||
"relativeLineNumbers",
|
||||
this.settings.relativeLineNumbers,
|
||||
);
|
||||
}
|
||||
|
||||
destroySession(session_id: number) {
|
||||
|
||||
78
www/src/js/editor/shortcuts-ui.ts
Normal file
78
www/src/js/editor/shortcuts-ui.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { BaseElement, defaultCss } from "../components";
|
||||
import { html, css, PropertyValueMap } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators.js";
|
||||
import { ace, Editor } from "./ace";
|
||||
|
||||
import "@shoelace-style/shoelace/dist/components/drawer/drawer.js";
|
||||
|
||||
import { SlDrawer } from "@shoelace-style/shoelace";
|
||||
import { Ref, createRef, ref } from "lit/directives/ref.js";
|
||||
|
||||
@customElement("ace-kb-menu")
|
||||
export class AceKeyboardShortcuts extends BaseElement {
|
||||
static styles = [
|
||||
defaultCss,
|
||||
css`
|
||||
.command {
|
||||
color: #c678dd;
|
||||
font-weight: normal;
|
||||
}
|
||||
.entry:hover {
|
||||
background-color: var(--sl-color-neutral-100);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.key {
|
||||
color: var(--sl-color-neutral-1000);
|
||||
font-weight: bold;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
editor?: Editor;
|
||||
@query('.drawer') accessor drawer: SlDrawer;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
// protected shouldUpdate(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): boolean {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
protected async firstUpdated() {
|
||||
if (!ace.require("ace/ext/menu_tools/get_editor_keyboard_shortcuts")) {
|
||||
await import("ace-builds/src-noconflict/ext-keybinding_menu");
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
var kbs: any[] = [];
|
||||
if (this.editor) {
|
||||
const getEditorKeybordShortcuts = ace.require(
|
||||
"ace/ext/menu_tools/get_editor_keyboard_shortcuts",
|
||||
).getEditorKeybordShortcuts;
|
||||
kbs = getEditorKeybordShortcuts(this.editor);
|
||||
}
|
||||
return html`
|
||||
<sl-drawer label="Editor Keyboard Shortcuts" class="drawer">
|
||||
<div>
|
||||
${kbs.map(
|
||||
(kb: any) =>
|
||||
html`<div class="entry">
|
||||
<span class="command">${kb.command}</span> :
|
||||
<span class="key">${kb.key}</span>
|
||||
</div>`,
|
||||
)}
|
||||
</div>
|
||||
</sl-drawer>
|
||||
`;
|
||||
}
|
||||
|
||||
show() {
|
||||
this.drawer.show();
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.drawer.hide();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ export const editorStyles = css`
|
||||
#editor {
|
||||
// border: 1px solid;
|
||||
// border-radius: 4px;
|
||||
@apply --ace-widget-editor;
|
||||
// @apply --ace-widget-editor;
|
||||
}
|
||||
#editorStatusbar {
|
||||
z-index: 9 !important;
|
||||
|
||||
Reference in New Issue
Block a user