Skip to content

Commit 6de77f5

Browse files
author
BF6 Portal Developer
committed
Docs/UI: credits + changelog; fix code preview init
1 parent 5663cb4 commit 6de77f5

File tree

10 files changed

+128
-11
lines changed

10 files changed

+128
-11
lines changed

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Changelog
2+
3+
This project follows a pragmatic changelog style (human-written notes) rather than auto-generated commit dumps.
4+
5+
## Unreleased (planned for v1.2.9)
6+
7+
### Fixes
8+
- **Selection Lists dropdowns:** address cases where dropdowns get stuck on “(loading selection lists…)” by improving runtime asset loading for Electron `file://` contexts.
9+
- **Presets:** allow saving after loading and editing a built-in preset (save-as copy / overwrite flow).
10+
11+
### Credits
12+
- Add explicit credit for the **Portal Docs** dataset used to populate block help/tooltips:
13+
- https://github.com/battlefield-portal-community/portal-docs
14+
15+
### CI/CD
16+
- GitHub Actions: release automation on tag push (creates GitHub Release and uploads Windows artifacts).
17+
18+
### Notes / Investigations log
19+
These are the key issues encountered recently and how they were fixed:
20+
- **“Container menuBarContainer not found”**: fixed by guarding MenuBar initialization when optional container isn’t present.
21+
- **Preset templates failing to load (`MissingConnection` / `modBlock` RULES)**: fixed by ensuring `modBlock` always provides a `RULES` statement input before loading presets.
22+
- **Packaged app missing `selection-lists.md`**: Electron build excludes `*.md`, so runtime now ships/loads `selection-lists.txt` instead.
23+
- **Code Preview stopped showing TypeScript**: caused by loading two Blockly instances (global script + webpack import) and serializing a workspace created by the “other” instance. Fixed by making the webpack Blockly instance the global `window.Blockly` and explicitly initializing the preview after workspace creation.
24+
25+
## v1.2.8
26+
27+
### Features & Improvements
28+
- Presets dropdown restored with **3 locked built-ins** (Andy6170 templates) + user save/delete.
29+
- Placeholder block auto-registration so community templates still render even if some block types are missing.
30+
- Selection list blocks use dynamic dropdowns (values sourced from `selection-lists` data).
31+
32+
### Fixes
33+
- Guarded UI init to avoid runtime errors when optional containers aren’t present.
34+
- Improved preset loading resilience and viewport focus (avoid “loaded offscreen / looks empty”).
35+
36+
### Known Issues
37+
- A persistent vertical scrollbar may still appear next to the toolbox flyout in certain states.

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
![License](https://img.shields.io/badge/license-ISC-green.svg)
55

66
Release notes: see `docs/RELEASE_NOTES_1.2.8.md`.
7+
Changelog: see `CHANGELOG.md`.
78

89
**BF6Portal Tool** is a standalone visual logic editor for **Battlefield 6 Portal**, built with **Electron** + **Google Blockly**. It aims to replicate the Portal Rules Editor workflow in a desktop app, with offline editing and quality-of-life tooling.
910

1011
## Screenshot
1112

12-
![BF6Portal Tool editor screenshot](docs/screenshots/editor.png)
13+
<img src="docs/screenshots/editor.png" alt="BF6Portal Tool editor screenshot" width="1100" />
14+
15+
> Note: The repo currently includes a tiny placeholder image. Replace `docs/screenshots/editor.png` with a real screenshot any time.
1316
1417
## Features
1518

@@ -77,6 +80,11 @@ The installer output is written to `dist/`.
7780

7881
Utilities live in `tools/` (used to generate/inspect blocks/toolboxes from Portal data).
7982

83+
## Credits
84+
85+
- Block help/tooltips and Portal data are derived from **Portal Docs** by the Battlefield Portal Community:
86+
- https://github.com/battlefield-portal-community/portal-docs
87+
8088
## License
8189

8290
ISC

TODO.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@
44
- **Location:** Left side of the screen, adjacent to the Blockly toolbox category list.
55
- **Current State:** CSS attempts to hide scrollbars on `.blocklyToolboxDiv`, `.blocklyToolbox`, and `.blocklyFlyout` have reduced but not fully eliminated the artifact in some states.
66
- **Potential Cause:** Electron/Chromium native scrollbar rendering on a dynamic container created by Blockly or the custom search bar injection.
7+
8+
## Upcoming (target: v1.2.9)
9+
10+
- [ ] **Selection Lists:** dropdowns can get stuck on “(loading selection lists…)” in some builds; improve runtime asset loading for Electron `file://`.
11+
- [ ] **Presets:** saving after editing a loaded preset should always work (save-as copy / overwrite flow).
12+
- [ ] **Credits:** add explicit credit/link for Portal Docs data source in About modal and repo README.

docs/RELEASE_NOTES_1.2.8.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Screenshot
44

5-
![BF6Portal Tool editor screenshot](screenshots/editor.png)
5+
<img src="screenshots/editor.png" alt="BF6Portal Tool editor screenshot" width="1100" />
66

77
## Features & Improvements
88
- **Refined Toolbox Structure:** The Blockly toolbox has been reorganized to better match the official Battlefield Portal Rules Editor layout.
@@ -19,5 +19,9 @@
1919
- **Scrollbar Styling:** Applied CSS fixes to suppress unwanted scrollbars on the toolbox container (work in progress).
2020
- **Presets dropdown restored:** Built-in presets (Rush/Conquest/Breakthrough) are visible again and **locked** from deletion; user presets can be saved/deleted normally.
2121

22+
## Credits
23+
- Portal data and block help/tooltips are derived from **Portal Docs** by the Battlefield Portal Community:
24+
- https://github.com/battlefield-portal-community/portal-docs
25+
2226
## Known Issues
2327
- A persistent vertical scrollbar may still appear next to the toolbox flyout in certain states. This is tracked for a future fix.

docs/screenshots/editor.png

7.72 KB
Loading

web_ui/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,14 @@
656656
>BattlefieldPortalHub</a>
657657
discord team.
658658
</div>
659+
<div style="margin-top: 8px; font-size: 0.98em; opacity: 0.92;">
660+
Portal data/help powered by <a
661+
href="https://github.com/battlefield-portal-community/portal-docs"
662+
target="_blank"
663+
rel="noopener noreferrer"
664+
style="color:#b0e0ff; font-weight: bold; text-decoration: underline;"
665+
>battlefield-portal-community/portal-docs</a>.
666+
</div>
659667
</div>
660668
</div>
661669
</div>

web_ui/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ function scheduleCodePreviewRefresh() {
148148
}
149149

150150
function initLiveCodePreview() {
151+
if (window.__bf6LiveCodePreviewBound) return;
151152
if (!window.workspace || typeof window.workspace.addChangeListener !== 'function') return;
153+
window.__bf6LiveCodePreviewBound = true;
152154
// Initial render
153155
scheduleCodePreviewRefresh();
154156
window.workspace.addChangeListener(() => {

web_ui/src/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ import './components/MenuBar.css';
3030
// Expose toolbox globally for legacy scripts
3131
(window as any).TOOLBOX_CONFIG = toolbox;
3232

33+
// This repo's shipped `web_ui/dist/index.html` currently loads both:
34+
// - legacy global Blockly via <script src="blockly/...">
35+
// - this webpack bundle which imports Blockly from node_modules
36+
// To avoid subtle mismatches (e.g., code preview / save using a different Blockly instance
37+
// than the workspace was created with), we deliberately point the global `window.Blockly`
38+
// at the same instance used by this bundle.
39+
(window as any).Blockly = Blockly;
40+
(window as any).__bf6_blockly = Blockly;
41+
3342
let menuBar: MenuBar | undefined;
3443

3544
// Initialize Menu Bar
@@ -152,6 +161,17 @@ try {
152161
// Expose workspace globally
153162
(window as any).workspace = ws;
154163

164+
// Legacy `web_ui/main.js` owns the Code Preview drawer implementation.
165+
// When the workspace is created by this bundle, explicitly kick the preview on.
166+
try {
167+
const g: any = window as any;
168+
if (typeof g.initLiveCodePreview === 'function') {
169+
g.initLiveCodePreview();
170+
}
171+
} catch (e) {
172+
console.warn('[BF6] Failed to init live code preview:', e);
173+
}
174+
155175
// Presets dropdown (3 locked built-ins + user save/delete).
156176
// NOTE: We bind in capture phase to prevent legacy `web_ui/main.js` handlers
157177
// (which use global Blockly) from interfering with this webpack/TS workspace.

web_ui/src/presets.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -573,15 +573,15 @@ function saveCurrentWorkspaceAsPreset(workspace: AnyWorkspace) {
573573
if (selected.kind === 'builtin' && (selected as any).name) defaultName = `${(selected as any).name} (Copy)`;
574574
if (selected.kind === 'user' && (selected as any).name) defaultName = (selected as any).name;
575575

576-
let name = prompt('Preset name:', defaultName);
577-
if (!name) return;
578-
name = name.trim();
576+
const raw = prompt('Preset name:', defaultName);
577+
if (raw == null) return;
578+
let name = raw.trim();
579579
if (!name) return;
580580

581581
// Prevent overwriting built-ins by name.
582582
if (builtins.some((b) => b.name.toLowerCase() === name.toLowerCase())) {
583-
alert('That name matches a locked built-in preset. Please choose a different name (it will be saved as a new preset).');
584-
return;
583+
// Friendly UX: don't hard-block. Auto-suffix so users can quickly save a copy.
584+
name = `${name} (Copy)`;
585585
}
586586

587587
const user = loadUserPresets();
@@ -652,8 +652,19 @@ export function initPresetsUI(workspace: AnyWorkspace) {
652652
saveBtn.addEventListener(
653653
'click',
654654
(e) => {
655+
e.preventDefault();
655656
e.stopImmediatePropagation();
656-
saveCurrentWorkspaceAsPreset(workspace);
657+
e.stopPropagation();
658+
try {
659+
saveCurrentWorkspaceAsPreset(workspace);
660+
} catch (err) {
661+
console.warn('[BF6] Save preset failed:', err);
662+
try {
663+
alert(`Save preset failed: ${String((err as any)?.message || err)}`);
664+
} catch {
665+
// ignore
666+
}
667+
}
657668
},
658669
true
659670
);

web_ui/src/selection_lists.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,30 @@ function parseSelectionListsMarkdown(md: string): SelectionListMap {
7575
}
7676

7777
async function fetchText(url: string): Promise<string> {
78-
const res = await fetch(url, { cache: 'no-store' });
79-
if (!res.ok) throw new Error(`HTTP ${res.status} for ${url}`);
80-
return await res.text();
78+
// Primary path: browser/Electron fetch.
79+
try {
80+
const res = await fetch(url, { cache: 'no-store' });
81+
if (!res.ok) throw new Error(`HTTP ${res.status} for ${url}`);
82+
return await res.text();
83+
} catch (e) {
84+
// Electron file:// can be flaky with fetch for local assets. Since this app
85+
// runs with Node integration enabled, fall back to fs when available.
86+
try {
87+
const g: any = globalThis as any;
88+
const req = g?.require;
89+
if (typeof req !== 'function') throw e;
90+
91+
const fs = req('fs') as typeof import('fs');
92+
const path = req('path') as typeof import('path');
93+
const { fileURLToPath } = req('url') as typeof import('url');
94+
95+
const assetUrl = new URL(url, window.location.href);
96+
const assetPath = fileURLToPath(assetUrl);
97+
return fs.readFileSync(path.resolve(assetPath), 'utf8');
98+
} catch {
99+
throw e;
100+
}
101+
}
81102
}
82103

83104
export async function preloadSelectionLists(): Promise<void> {

0 commit comments

Comments
 (0)