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
32 changes: 32 additions & 0 deletions .github/workflows/_ci-node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
# This workflow is centrally managed in https://github.com/LizardByte/.github/
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in
# the above-mentioned repo.

# To use, add the `npm-pkg` repository label to identify repositories that should trigger this workflow.

# This will run standard CI for Node.js/npm/TypeScript projects.

name: CI-Node
permissions: {}

on:
pull_request:
push:
branches:
- master

concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

jobs:
call-ci-node:
name: CI-Node
uses: LizardByte/.github/.github/workflows/__call-ci-node.yml@master
if: ${{ github.repository != 'LizardByte/.github' }}
permissions:
contents: write # required for release_setup action
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
GH_TOKEN: ${{ secrets.GH_BOT_TOKEN }}
26 changes: 0 additions & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,3 @@ jobs:
clean_gh_pages: true
gh_bot_name: ${{ vars.GH_BOT_NAME }}
target_branch: gh-pages

release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
permissions:
contents: write # needed for setup-release-action
runs-on: ubuntu-latest
steps:
- name: Setup Release
id: setup-release
uses: LizardByte/actions/actions/release_setup@39c468549cfb87ccb917e5e5342e18abc926dc48 # v2026.909.30231
with:
github_token: ${{ secrets.GH_BOT_TOKEN }}

- name: Create Release
id: action
uses: LizardByte/actions/actions/release_create@39c468549cfb87ccb917e5e5342e18abc926dc48 # v2026.909.30231
with:
allowUpdates: false
artifacts: ''
body: ${{ steps.setup-release.outputs.release_body }}
draft: true
generateReleaseNotes: ${{ steps.setup-release.outputs.release_generate_release_notes }}
name: ${{ steps.setup-release.outputs.release_tag }}
prerelease: true
tag: ${{ steps.setup-release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# ignore JetBrains project
.idea/

# Ignore Node.js dependencies
node_modules/

# Ignore test results
coverage/
junit.xml

_site/
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<div align="center">
<a href="https://github.com/LizardByte/LizardByte.github.io/actions/workflows/ci.yml?query=branch%3Amaster"><img src="https://img.shields.io/github/actions/workflow/status/lizardbyte/LizardByte.github.io/ci.yml.svg?branch=master&label=build&logo=github&style=for-the-badge" alt="GitHub Workflow Status (CI)"></a>
<a href="https://codecov.io/gh/LizardByte/LizardByte.github.io"><img src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fapp.lizardbyte.dev%2Fdashboard%2Fshields%2Fcodecov%2FLizardByte.github.io.json&style=for-the-badge&logo=codecov" alt="Codecov"></a>
<a href="https://sonarcloud.io/project/overview?id=LizardByte_LizardByte.github.io"><img src="https://img.shields.io/sonar/quality_gate/LizardByte_LizardByte.github.io.svg?server=https%3A%2F%2Fsonarcloud.io&style=for-the-badge&logo=sonarqubecloud&label=sonarcloud" alt="SonarCloud"></a>
</div>

Expand Down
34 changes: 10 additions & 24 deletions assets/js/gamepad-tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ document.addEventListener('DOMContentLoaded', function() {
updateStatus(`Gamepad ${e.gamepad.id} connected`);

// Start the loop if it's not already running
if (!animationFrameId) {
if (animationFrameId === null) {
startGamepadLoop();
}
});
Expand Down Expand Up @@ -149,21 +149,17 @@ document.addEventListener('DOMContentLoaded', function() {
});

// Initialize controls for the selected gamepad
if (activeGamepadIndex !== null) {
initGamepadButtons();
initGamepadAxes();
initGamepadVisual();
}
initGamepadButtons();
initGamepadAxes();
initGamepadVisual();
} else {
gamepadSelectorContainer.style.display = 'none';
gamepadInfoSection.style.display = 'none';
}
}

function initGamepadVisual() {
const gamepad = activeGamepadIndex === null
? null
: navigator.getGamepads()[activeGamepadIndex];
const gamepad = navigator.getGamepads()[activeGamepadIndex];
gamepadVisualizer.mount(gamepad);
}

Expand All @@ -172,8 +168,6 @@ document.addEventListener('DOMContentLoaded', function() {
const buttonsContainer = document.getElementById('buttons-container');
buttonsContainer.innerHTML = '';

if (activeGamepadIndex === null) return;

const gamepad = navigator.getGamepads()[activeGamepadIndex];
if (!gamepad) return;

Expand Down Expand Up @@ -241,8 +235,6 @@ document.addEventListener('DOMContentLoaded', function() {
const axesContainer = document.getElementById('axes-container');
axesContainer.innerHTML = '';

if (activeGamepadIndex === null) return;

const gamepad = navigator.getGamepads()[activeGamepadIndex];
if (!gamepad) return;

Expand Down Expand Up @@ -529,24 +521,18 @@ document.addEventListener('DOMContentLoaded', function() {

// Start the gamepad polling loop
function startGamepadLoop() {
if (animationFrameId) return;

// Make sure UI elements are initialized when starting the loop
if (activeGamepadIndex !== null) {
initGamepadButtons();
initGamepadAxes();
initGamepadVisual();
}
initGamepadButtons();
initGamepadAxes();
initGamepadVisual();

gamepadLoop();
}

// Stop the gamepad polling loop
function stopGamepadLoop() {
if (animationFrameId) {
cancelAnimationFrame(animationFrameId);
animationFrameId = null;
}
cancelAnimationFrame(animationFrameId);
animationFrameId = null;
}

// The main gamepad polling loop
Expand Down
63 changes: 63 additions & 0 deletions assets/js/release-versions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Update stable and prerelease links with release data from GitHub.
*
* @param {object} options Release display options.
* @param {string} options.repository GitHub repository in owner/name form.
* @param {string} options.stableButtonSelector Selector for the stable release link.
* @param {string} options.stableVersionSelector Selector for the stable version text.
* @param {string} options.prereleaseButtonSelector Selector for the prerelease link.
* @param {string} options.prereleaseVersionSelector Selector for the prerelease version text.
* @returns {Promise<void>} Promise fulfilled after the release display is updated.
*/
async function updateGitHubReleaseVersions(options) {
const repositoryPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u;
const [owner, repository] = options.repository.split('/');
const invalidSegments = new Set(['.', '..']);
if (
!repositoryPattern.test(options.repository)
|| invalidSegments.has(owner)
|| invalidSegments.has(repository)
) {
throw new TypeError('repository must use the owner/name format');
}

const stableButton = document.querySelector(options.stableButtonSelector);
const stableVersion = document.querySelector(options.stableVersionSelector);
const prereleaseButton = document.querySelector(options.prereleaseButtonSelector);
const prereleaseVersion = document.querySelector(options.prereleaseVersionSelector);
if (!stableButton || !stableVersion || !prereleaseButton || !prereleaseVersion) {
throw new TypeError('release display selectors must match existing elements');
}

const apiUrl = `https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repository)}/releases`;
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`GitHub releases request failed with status ${response.status}`);
}

const releases = await response.json();
if (!Array.isArray(releases)) {
throw new TypeError('GitHub releases response must be an array');
}

const latestStableRelease = releases.find(release => !release.prerelease);
stableButton.classList.toggle('d-none', !latestStableRelease);
if (!latestStableRelease) {
prereleaseButton.classList.add('d-none');
return;
}

stableButton.href = latestStableRelease.html_url;
stableVersion.textContent = latestStableRelease.tag_name;

const latestPrerelease = releases.find(release => release.prerelease);
const prereleaseIsNewer = latestPrerelease
&& new Date(latestPrerelease.published_at) > new Date(latestStableRelease.published_at);
prereleaseButton.classList.toggle('d-none', !prereleaseIsNewer);
if (prereleaseIsNewer) {
prereleaseButton.href = latestPrerelease.html_url;
prereleaseVersion.textContent = latestPrerelease.tag_name;
}
}

globalThis.updateGitHubReleaseVersions = updateGitHubReleaseVersions;
11 changes: 0 additions & 11 deletions assets/js/remove-widgetbot-crate.js

This file was deleted.

41 changes: 41 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import globals from 'globals';
import pluginJs from '@eslint/js';
import pluginJest from 'eslint-plugin-jest';

export default [
pluginJs.configs.recommended,
{
ignores: [
'coverage/**',
'node_modules/**',
],
},
{
files: ['assets/js/release-versions.js'],
languageOptions: {
globals: {
...globals.browser,
},
},
},
{
files: ['tests/**/*.test.cjs'],
...pluginJest.configs['flat/recommended'],
languageOptions: {
ecmaVersion: 2022,
sourceType: 'commonjs',
globals: {
...globals.browser,
...globals.node,
...globals.jest,
},
},
rules: {
'jest/no-disabled-tests': 'error',
'jest/no-focused-tests': 'error',
'jest/no-identical-title': 'error',
'jest/prefer-to-have-length': 'error',
'jest/valid-expect': 'error',
},
},
];
Loading