changelog dialog
This commit is contained in:
26
CHANGELOG.md
Normal file
26
CHANGELOG.md
Normal file
@@ -0,0 +1,26 @@
|
||||
## v0.2.0
|
||||
|
||||
### Share VM State!
|
||||
|
||||
New in this release is the ability to share the entire VM with you share a link. This means code; connected devices and their state; as well as the state of the stack, registers, and line number of the active IC!
|
||||
|
||||
Additionally you can now save and load any number of sessions in your browser. Access this functionality from the main menu.
|
||||
|
||||
Also! the project has officially moved to https://ic10emu.dev . Old share links *should* redirect, but if not simply copy the fragment (the part of the url starting with the `#` symbol)
|
||||
|
||||
#### List of changes
|
||||
|
||||
- Move build system from Webpack to [Rsbuild](https://rsbuild.dev/) (way faster build times).
|
||||
- VM now supports exporting and restoring a frozen state.
|
||||
- Share links updates to use frozen vm state.
|
||||
- Save and load sessions from the browser's IndexedDB storage.
|
||||
- project now includes tailwindcss to make frontend dev easier.
|
||||
- Changelog dialog to notify users of updates.
|
||||
|
||||
## v0.1.0
|
||||
|
||||
### **Initial Release**:
|
||||
|
||||
IC10emu is released to the public! edit and share your IC10 scripts!
|
||||
|
||||
- view and edit stack and registers
|
||||
@@ -62,6 +62,7 @@
|
||||
"jquery": "^3.7.1",
|
||||
"lit": "^3.1.3",
|
||||
"lzma-web": "^3.0.1",
|
||||
"marked": "^12.0.2",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"uuid": "^9.0.1",
|
||||
"vm-browserify": "^1.1.2"
|
||||
|
||||
9
www/pnpm-lock.yaml
generated
9
www/pnpm-lock.yaml
generated
@@ -53,6 +53,9 @@ dependencies:
|
||||
lzma-web:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
marked:
|
||||
specifier: ^12.0.2
|
||||
version: 12.0.2
|
||||
stream-browserify:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
@@ -2920,6 +2923,12 @@ packages:
|
||||
resolution: {integrity: sha512-sb5cdfd+PLNljK/HUgYzvnz4G7r0GFK8sonyGrqJS0FVyUQjFYcnmU2LqTWFi6r48lH1ZBstnxyLWepKM/t7QA==}
|
||||
dev: false
|
||||
|
||||
/marked@12.0.2:
|
||||
resolution: {integrity: sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/md5.js@1.3.5:
|
||||
resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
|
||||
dependencies:
|
||||
|
||||
@@ -37,6 +37,13 @@ export default defineConfig({
|
||||
),
|
||||
to: "shoelace/assets",
|
||||
},
|
||||
{
|
||||
from: path.resolve(
|
||||
__dirname,
|
||||
"../CHANGELOG.md"
|
||||
),
|
||||
to: "static/",
|
||||
}
|
||||
],
|
||||
}),
|
||||
new CssExtractRspackPlugin(),
|
||||
|
||||
@@ -21,6 +21,8 @@ import { openFile, saveFile } from "../utils";
|
||||
import "../virtual_machine/ui";
|
||||
import "./save";
|
||||
import { SaveDialog } from "./save";
|
||||
import "./welcome";
|
||||
import { AppWelcome } from "./welcome";
|
||||
|
||||
declare global {
|
||||
const __COMMIT_HASH__: string;
|
||||
@@ -61,6 +63,7 @@ export class App extends BaseElement {
|
||||
@query("ace-ic10") editor: IC10Editor;
|
||||
@query("session-share-dialog") shareDialog: ShareSessionDialog;
|
||||
@query("save-dialog") saveDialog: SaveDialog;
|
||||
@query("app-welcome") appWelcome: AppWelcome;
|
||||
|
||||
// get editor() {
|
||||
// return this.renderRoot.querySelector("ace-ic10") as IC10Editor;
|
||||
@@ -83,6 +86,7 @@ export class App extends BaseElement {
|
||||
root.addEventListener("app-export", this._handleExport.bind(this));
|
||||
root.addEventListener("app-save", this._handleSave.bind(this));
|
||||
root.addEventListener("app-load", this._handleLoad.bind(this));
|
||||
root.addEventListener("app-changelog", this._handleChangelog.bind(this));
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -104,11 +108,54 @@ export class App extends BaseElement {
|
||||
</div>
|
||||
<session-share-dialog></session-share-dialog>
|
||||
<save-dialog></save-dialog>
|
||||
<app-welcome @sl-after-hide=${this.afterWelcomeHide}></app-welcome>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
firstUpdated(): void {}
|
||||
firstUpdated(): void {
|
||||
setTimeout(() => {
|
||||
this.checkSeenVersion();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
checkSeenVersion() {
|
||||
const seenVersionsStr = window.localStorage.getItem("seenVersions");
|
||||
let seenVersions: string[] = [];
|
||||
if (seenVersionsStr !== null && seenVersionsStr.length > 0) {
|
||||
try {
|
||||
const saved = JSON.parse(seenVersionsStr);
|
||||
seenVersions = saved;
|
||||
} catch (e) {
|
||||
console.log("error pulling seen versions", e);
|
||||
}
|
||||
}
|
||||
const ourVer = `${this.appVersion}_${this.gitVer}_${this.buildDate}`;
|
||||
if (!seenVersions.includes(ourVer)) {
|
||||
this.appWelcome.show();
|
||||
}
|
||||
}
|
||||
|
||||
afterWelcomeHide() {
|
||||
const seenVersionsStr = window.localStorage.getItem("seenVersions");
|
||||
const seenVersions: string[] = [];
|
||||
if (seenVersionsStr !== null && seenVersionsStr.length > 0) {
|
||||
try {
|
||||
const saved = JSON.parse(seenVersionsStr);
|
||||
seenVersions.concat(saved);
|
||||
} catch (e) {
|
||||
console.log("error pulling seen versions", e);
|
||||
}
|
||||
}
|
||||
const unique = new Set(seenVersions);
|
||||
const ourVer = `${this.appVersion}_${this.gitVer}_${this.buildDate}`;
|
||||
if (this.appWelcome.dontShowAgain) {
|
||||
unique.add(ourVer)
|
||||
} else {
|
||||
unique.delete(ourVer)
|
||||
}
|
||||
window.localStorage.setItem("seenVersions", JSON.stringify(Array.from(unique)));
|
||||
}
|
||||
|
||||
_handleShare(_e: Event) {
|
||||
// TODO:
|
||||
@@ -130,6 +177,10 @@ export class App extends BaseElement {
|
||||
_handleOpenFile(_e: Event) {
|
||||
openFile(window.Editor.editor);
|
||||
}
|
||||
|
||||
_handleChangelog(_e: Event) {
|
||||
this.appWelcome.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
1113
www/src/ts/app/gfm-styles.ts
Normal file
1113
www/src/ts/app/gfm-styles.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -157,6 +157,11 @@ export class Nav extends BaseElement {
|
||||
<sl-menu-item value="preset-demo"> Demo </sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-menu-item>
|
||||
<sl-divider></sl-divider>
|
||||
<sl-menu-item value="changelog">
|
||||
Changelog
|
||||
<sl-icon name="journal-text" slot="prefix"></sl-icon>
|
||||
</sl-menu-item>
|
||||
</sl-menu>
|
||||
</sl-dropdown>
|
||||
</div>
|
||||
@@ -246,6 +251,10 @@ export class Nav extends BaseElement {
|
||||
break;
|
||||
case "preset-demo":
|
||||
window.location.hash = "demo";
|
||||
break;
|
||||
case "changelog":
|
||||
this.dispatchEvent(new CustomEvent("app-changelog", { bubbles: true }));
|
||||
break;
|
||||
default:
|
||||
console.log("Unknown main menu item", item.value);
|
||||
}
|
||||
|
||||
75
www/src/ts/app/welcome.ts
Normal file
75
www/src/ts/app/welcome.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { html, css } from "lit";
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
import { customElement, property, query, state } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "../components";
|
||||
import { SlDialog, SlSwitch } from "@shoelace-style/shoelace";
|
||||
import { until } from "lit/directives/until.js";
|
||||
|
||||
import "@shoelace-style/shoelace/dist/components/spinner/spinner.js";
|
||||
import '@shoelace-style/shoelace/dist/components/switch/switch.js';
|
||||
|
||||
import { marked } from "marked";
|
||||
import { gfmStyles } from "./gfm-styles";
|
||||
|
||||
@customElement("app-welcome")
|
||||
export class AppWelcome extends BaseElement {
|
||||
static styles = [
|
||||
...defaultCss,
|
||||
gfmStyles,
|
||||
css`
|
||||
.welcome-dialog {
|
||||
--width: 42rem;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@property({ type: Boolean }) dontShowAgain: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.dontShowAgain = true;
|
||||
}
|
||||
|
||||
@query("sl-dialog.welcome-dialog") dialog: SlDialog;
|
||||
@query("sl-switch.dont-show-switch") dontShowSwitch: SlSwitch;
|
||||
|
||||
hide() {
|
||||
this.dialog?.hide();
|
||||
}
|
||||
|
||||
show() {
|
||||
this.dialog?.show();
|
||||
}
|
||||
|
||||
async getChangelog() {
|
||||
const response = await fetch("static/CHANGELOG.md");
|
||||
const blob = await response.blob();
|
||||
const markdown = await blob.text();
|
||||
const renderedText = await marked(markdown, {
|
||||
async: true,
|
||||
gfm: true,
|
||||
});
|
||||
return unsafeHTML(renderedText);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<sl-dialog class="welcome-dialog" label="Changlog">
|
||||
<h6>Hey there!</h6>
|
||||
<p>Looks like there have been some updates since you've last visit.</p>
|
||||
<br />
|
||||
<p>Check out the changelog below.</p>
|
||||
<div class="p-4 border-1 border-solid rounded-lg max-h-80 mt-4 overflow-y-auto bg-neutral-900 markdown-body">
|
||||
${until(this.getChangelog(), html`<sl-spinner class="ml-2 my-4" style="font-size: 2rem;"></sl-spinner>`)}
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<sl-switch class="dont-show-switch" size="small" ?checked=${this.dontShowAgain} @sl-change=${this._dontShowSwitchChange} >Don't show again</sl-switch>
|
||||
</div>
|
||||
</sl-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
_dontShowSwitchChange(e: CustomEvent) {
|
||||
this.dontShowAgain = this.dontShowSwitch.checked;
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,7 @@ export function docReady(fn: () => void) {
|
||||
}
|
||||
|
||||
function isZeroNegative(zero: number) {
|
||||
const isZero = zero === 0;
|
||||
const isNegative = 1 / zero === -Infinity;
|
||||
return isNegative && isZero;
|
||||
return Object.is(zero, -0)
|
||||
}
|
||||
|
||||
export function numberToString(n: number): string {
|
||||
|
||||
Reference in New Issue
Block a user