Merge pull request 'Add tweak to set the default Hotbar page' (#34) from feature/default-hotbar-page into main
Reviewed-on: #34
This commit is contained in:
commit
52cf835a52
14 changed files with 93 additions and 2091 deletions
|
|
@ -1,2 +1,5 @@
|
|||
# The absolute path to the Foundry installation to create symlinks to
|
||||
FOUNDRY_ROOT=""
|
||||
|
||||
# The manifest file for the module/system
|
||||
MANIFEST="./module.json"
|
||||
|
|
|
|||
|
|
@ -1,89 +1,46 @@
|
|||
on: [ workflow_dispatch ]
|
||||
env:
|
||||
MANIFEST: "module.json"
|
||||
jobs:
|
||||
create-artifacts:
|
||||
name: "Create artifacts"
|
||||
create-draft-release:
|
||||
name: "Create Draft Release"
|
||||
runs-on: act
|
||||
outputs:
|
||||
version: ${{steps.version.outputs.version}}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm clean-install
|
||||
|
||||
- id: version
|
||||
run: cat module.json | echo version=`jq -r ".version"` >> "$FORGEJO_OUTPUT"
|
||||
run: cat system.json | echo version=`jq -r ".version"` >> "$FORGEJO_OUTPUT"
|
||||
|
||||
- name: Assert that the tag doesn't exist
|
||||
run: node scripts/tagExists.mjs
|
||||
run: node scripts/src/tagExists.mjs
|
||||
env:
|
||||
TAG_NAME: "v${{steps.version.outputs.version}}"
|
||||
|
||||
- name: Compress files
|
||||
run: zip -r release.zip langs module styles templates README.md assets
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: https://data.forgejo.org/forgejo/upload-artifact@v4
|
||||
with:
|
||||
path: |
|
||||
module.json
|
||||
release.zip
|
||||
scripts/*.mjs
|
||||
package-lock.json
|
||||
package.json
|
||||
retention-days: 7
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
forgejo-release:
|
||||
name: "Create Forgejo release"
|
||||
runs-on: act
|
||||
needs:
|
||||
- create-artifacts
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: https://data.forgejo.org/forgejo/download-artifact@v4
|
||||
with:
|
||||
merge-multiple: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm i
|
||||
|
||||
- id: version
|
||||
run: cat module.json | echo version=`jq -r ".version"` >> "$FORGEJO_OUTPUT"
|
||||
# Compendia steps
|
||||
- name: Build compendia
|
||||
run: "npm run data:build"
|
||||
- name: Remove compendia source
|
||||
run: "rm -rf packs/**/_source"
|
||||
|
||||
- name: Update manifest
|
||||
run: node scripts/prepareManifest.mjs
|
||||
run: node scripts/src/prepareManifest.mjs
|
||||
env:
|
||||
DOWNLOAD_URL: "${{forgejo.server_url}}/${{forgejo.repository}}/releases/download/v${{steps.version.outputs.version}}/release.zip"
|
||||
LATEST_URL: "${{forgejo.server_url}}/${{forgejo.repository}}/releases/download/latest/module.json"
|
||||
LATEST_URL: "${{forgejo.server_url}}/${{forgejo.repository}}/releases/download/latest/system.json"
|
||||
|
||||
- name: Add manifest into release archive
|
||||
run: zip release.zip --update module.json
|
||||
- name: Compress files
|
||||
run: zip -r release.zip langs module styles templates README.md assets LICENSE
|
||||
|
||||
- name: Upload archive to s3
|
||||
run: node scripts/uploadToS3.mjs
|
||||
env:
|
||||
TAG: "v${{steps.version.outputs.version}}"
|
||||
FILE: "release.zip"
|
||||
S3_BUCKET: "${{vars.S3_BUCKET}}"
|
||||
S3_REGION: "${{vars.S3_REGION}}"
|
||||
S3_KEY: "${{secrets.S3_KEY}}"
|
||||
S3_SECRET: "${{secrets.S3_SECRET}}"
|
||||
S3_ENDPOINT: "${{vars.S3_ENDPOINT}}"
|
||||
|
||||
- name: Upload manifest to s3
|
||||
run: node scripts/uploadToS3.mjs
|
||||
env:
|
||||
TAG: "v${{steps.version.outputs.version}}"
|
||||
FILE: "module.json"
|
||||
S3_BUCKET: "${{vars.S3_BUCKET}}"
|
||||
S3_REGION: "${{vars.S3_REGION}}"
|
||||
S3_KEY: "${{secrets.S3_KEY}}"
|
||||
S3_SECRET: "${{secrets.S3_SECRET}}"
|
||||
S3_ENDPOINT: "${{vars.S3_ENDPOINT}}"
|
||||
|
||||
- name: Create draft release
|
||||
run: node scripts/createForgejoRelease.mjs
|
||||
- name: Create forgejo release
|
||||
run: node scripts/src/createForgejoRelease.mjs
|
||||
env:
|
||||
TAG: "v${{steps.version.outputs.version}}"
|
||||
CDN_URL: "${{vars.CDN_URL}}"
|
||||
|
|
|
|||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "scripts"]
|
||||
path = scripts
|
||||
url = https://git.varify.ca/Foundry/scripts.git
|
||||
|
|
@ -17,6 +17,10 @@
|
|||
"name": "Chat Background",
|
||||
"hint": "(v13+) Adds a background to the chat tab of the right-hand sidebar."
|
||||
},
|
||||
"defaultHotbarPage": {
|
||||
"name": "Default Hotbar Page",
|
||||
"hint": "What page the hotbar will default to when loading into Foundry."
|
||||
},
|
||||
"hotbarButtonGap": {
|
||||
"name": "Hotbar Button Gap",
|
||||
"hint": "(v13+) Allows changing the amount of space between the hotbar buttons."
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
// Settings
|
||||
// Tweaks
|
||||
import { addGlobalDocReferrer } from "../tweaks/addGlobalDocReferrer.mjs";
|
||||
import { autoUnpauseOnLoad } from "../tweaks/autoUnpauseOnLoad.mjs";
|
||||
import { chatImageLinks } from "../tweaks/chatImageLinks.mjs";
|
||||
import { chatSidebarBackground } from "../tweaks/chatSidebarBackground.mjs";
|
||||
import { defaultHotbarPage } from "../tweaks/defaultHotbarPage.mjs";
|
||||
import { hotbarButtonGap } from "../tweaks/hotbarButtonGap.mjs";
|
||||
import { hotbarButtonSize } from "../tweaks/hotbarButtonSize.mjs";
|
||||
import { preventTokenRotation } from "../tweaks/preventTokenRotation.mjs";
|
||||
|
|
@ -40,6 +41,7 @@ Hooks.on(`setup`, () => {
|
|||
restricted: false,
|
||||
type: HotbarSettingsMenu,
|
||||
});
|
||||
defaultHotbarPage();
|
||||
hotbarButtonSize();
|
||||
hotbarButtonGap();
|
||||
repositionHotbar();
|
||||
|
|
|
|||
37
module/tweaks/defaultHotbarPage.mjs
Normal file
37
module/tweaks/defaultHotbarPage.mjs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { SettingStatusEnum, status } from "../utils/SettingStatus.mjs";
|
||||
import { __ID__ } from "../consts.mjs";
|
||||
import { Logger } from "../utils/Logger.mjs";
|
||||
import { preventTweakRegistration } from "../utils/preRegisterTweak.mjs";
|
||||
import { registerCategorySetting } from "../utils/SubMenuSettings.mjs";
|
||||
|
||||
export const key = `defaultHotbarPage`;
|
||||
|
||||
export function defaultHotbarPage() {
|
||||
status[key] = SettingStatusEnum.Unknown;
|
||||
if (preventTweakRegistration(key)) { return };
|
||||
|
||||
// #region Registration
|
||||
Logger.log(`Registering setting: ${key}`);
|
||||
registerCategorySetting(`hotbar`, __ID__, key, {
|
||||
name: `OFT.setting.${key}.name`,
|
||||
hint: `OFT.setting.${key}.hint`,
|
||||
scope: `user`,
|
||||
type: new foundry.data.fields.NumberField({
|
||||
min: 1,
|
||||
max: 5,
|
||||
step: 1,
|
||||
}),
|
||||
default: 1,
|
||||
config: true,
|
||||
requiresReload: false,
|
||||
});
|
||||
// #endregion Registration
|
||||
|
||||
// #region Implementation
|
||||
Hooks.once(`ready`, () => {
|
||||
ui.hotbar.changePage(game.settings.get(__ID__, key));
|
||||
});
|
||||
// #endregion Implementation
|
||||
|
||||
status[key] = SettingStatusEnum.Registered;
|
||||
};
|
||||
1788
package-lock.json
generated
1788
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +1,13 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@aws-sdk/client-s3": "^3.946.0",
|
||||
"@eslint/js": "^9.8.0",
|
||||
"@foundryvtt/foundryvtt-cli": "^1.0.3",
|
||||
"@stylistic/eslint-plugin": "^2.6.1",
|
||||
"axios": "^1.13.2",
|
||||
"dotenv": "^17.2.2",
|
||||
"eslint": "^9.8.0",
|
||||
"globals": "^15.9.0"
|
||||
"globals": "^15.9.0",
|
||||
"scripts": "file:./scripts"
|
||||
},
|
||||
"scripts": {
|
||||
"link": "node scripts/linkFoundry.mjs",
|
||||
"link": "node scripts/src/linkFoundry.mjs",
|
||||
"lint": "eslint --fix",
|
||||
"lint:nofix": "eslint"
|
||||
}
|
||||
|
|
|
|||
1
scripts
Submodule
1
scripts
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit edfb087341d74e5fb1398d3833e3d4c8261d215b
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const {
|
||||
TAG,
|
||||
FORGEJO_SERVER_URL: WEB_URL,
|
||||
FORGEJO_API_URL: API,
|
||||
FORGEJO_REPOSITORY: REPO,
|
||||
FORGEJO_TOKEN: TOKEN,
|
||||
CDN_URL,
|
||||
} = process.env;
|
||||
|
||||
async function addReleaseAsset(releaseID, name) {
|
||||
return axios.post(
|
||||
`${API}/repos/${REPO}/releases/${releaseID}/assets`,
|
||||
{ external_url: `${CDN_URL}/${REPO}/${TAG}/${name}`, },
|
||||
{
|
||||
headers: {
|
||||
Authorization: `token ${TOKEN}`,
|
||||
"Content-Type": `multipart/form-data`,
|
||||
},
|
||||
params: { name },
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
async function main() {
|
||||
|
||||
// Initial Release Data
|
||||
const release = await axios.post(
|
||||
`${API}/repos/${REPO}/releases`,
|
||||
{
|
||||
name: TAG,
|
||||
tag_name: TAG,
|
||||
draft: true,
|
||||
hide_archive_links: true,
|
||||
body: `<!-- Manifest URL: ${WEB_URL}/${REPO}/releases/download/${TAG}/module.json -->`,
|
||||
},
|
||||
{
|
||||
headers: { Authorization: `token ${TOKEN}` },
|
||||
}
|
||||
);
|
||||
|
||||
try {
|
||||
await addReleaseAsset(release.data.id, `release.zip`);
|
||||
await addReleaseAsset(release.data.id, `module.json`);
|
||||
} catch (e) {
|
||||
console.error(`Failed to add assets to the release`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
console.log(`Release created`);
|
||||
};
|
||||
|
||||
main();
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import { existsSync } from "fs";
|
||||
import { symlink, unlink } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import { config } from "dotenv";
|
||||
|
||||
config({ quiet: true });
|
||||
|
||||
const root = process.env.FOUNDRY_ROOT;
|
||||
|
||||
// Early exit
|
||||
if (!root) {
|
||||
console.error(`Must provide a FOUNDRY_ROOT environment variable`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
// Assert Foundry exists
|
||||
if (!existsSync(root)) {
|
||||
console.error(`Foundry root not found.`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
// Removing existing symlink
|
||||
if (existsSync(`foundry`)) {
|
||||
console.log(`Attempting to unlink foundry instance`);
|
||||
try {
|
||||
await unlink(`foundry`);
|
||||
} catch {
|
||||
console.error(`Failed to unlink foundry folder.`);
|
||||
process.exit(1);
|
||||
};
|
||||
};
|
||||
|
||||
// Account for if the root is pointing at an Electron install
|
||||
let targetRoot = root;
|
||||
if (existsSync(join(root, `resources`, `app`))) {
|
||||
console.log(`Switching to use the "${root}/resources/app" directory`);
|
||||
targetRoot = join(root, `resources`, `app`);
|
||||
};
|
||||
|
||||
// Create symlink
|
||||
console.log(`Linking foundry source into folder`);
|
||||
try {
|
||||
await symlink(targetRoot, `foundry`);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
};
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
The intent of this script is to do all of the modifications of the
|
||||
manifest file that we need to do in order to release the system.
|
||||
This can include removing dev-only fields/attributes that end
|
||||
users will never, and should never, care about nor need.
|
||||
*/
|
||||
import { readFile, writeFile } from "fs/promises";
|
||||
|
||||
const MANIFEST_PATH = `module.json`;
|
||||
|
||||
const {
|
||||
DOWNLOAD_URL,
|
||||
LATEST_URL,
|
||||
} = process.env;
|
||||
|
||||
let manifest;
|
||||
try {
|
||||
manifest = JSON.parse(await readFile(MANIFEST_PATH, `utf-8`));
|
||||
console.log(`Manifest loaded from disk`);
|
||||
} catch {
|
||||
console.error(`Failed to parse manifest file.`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
console.log(`Updating download/manifest URLs`);
|
||||
manifest.download = DOWNLOAD_URL;
|
||||
manifest.manifest = LATEST_URL;
|
||||
|
||||
// Filter out dev-only resources
|
||||
if (manifest.esmodules) {
|
||||
console.log(`Removing dev-only esmodules`);
|
||||
manifest.esmodules = manifest.esmodules.filter(
|
||||
filepath => !filepath.startsWith(`dev/`)
|
||||
);
|
||||
};
|
||||
|
||||
// Remove dev flags
|
||||
console.log(`Cleaning up flags`);
|
||||
delete manifest.flags?.hotReload;
|
||||
delete manifest.flags?.inDev;
|
||||
if (Object.keys(manifest.flags).length === 0) {
|
||||
delete manifest.flags;
|
||||
};
|
||||
|
||||
await writeFile(MANIFEST_PATH, JSON.stringify(manifest, undefined, `\t`));
|
||||
console.log(`Manifest written back to disk`);
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import axios from "axios";
|
||||
|
||||
const {
|
||||
TAG_NAME,
|
||||
FORGEJO_API_URL: API_URL,
|
||||
FORGEJO_REPOSITORY: REPO,
|
||||
FORGEJO_TOKEN: TOKEN,
|
||||
} = process.env;
|
||||
|
||||
|
||||
async function main() {
|
||||
|
||||
if (!TAG_NAME) {
|
||||
console.log(`Tag name must not be blank`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
const requestURL = `${API_URL}/repos/${REPO}/tags/${TAG_NAME}`;
|
||||
|
||||
const response = await axios.get(
|
||||
requestURL,
|
||||
{
|
||||
headers: { Authorization: `token ${TOKEN}` },
|
||||
validateStatus: () => true,
|
||||
},
|
||||
);
|
||||
|
||||
// We actually *want* an error when the tag exists, instead of when
|
||||
// it doesn't
|
||||
if (response.status === 200) {
|
||||
console.log(`Tag with name "${TAG_NAME}" already exists`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
console.log(`Tag with name "${TAG_NAME}" not found, proceeding`);
|
||||
};
|
||||
|
||||
main();
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
||||
import { createReadStream } from "fs";
|
||||
|
||||
const requiredEnvVariables = [
|
||||
`TAG`, `FILE`,
|
||||
`FORGEJO_REPOSITORY`,
|
||||
`S3_BUCKET`, `S3_REGION`, `S3_KEY`, `S3_SECRET`, `S3_ENDPOINT`,
|
||||
];
|
||||
|
||||
async function main() {
|
||||
|
||||
// Assert all of the required env variables are present
|
||||
const missing = [];
|
||||
for (const envVar of requiredEnvVariables) {
|
||||
if (!(envVar in process.env)) {
|
||||
missing.push(envVar);
|
||||
};
|
||||
};
|
||||
if (missing.length > 0) {
|
||||
console.error(`Missing the following required environment variables: ${missing.join(`, `)}`);
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
const {
|
||||
TAG,
|
||||
S3_ENDPOINT,
|
||||
S3_REGION,
|
||||
S3_KEY,
|
||||
S3_SECRET,
|
||||
S3_BUCKET,
|
||||
FILE,
|
||||
FORGEJO_REPOSITORY: REPO,
|
||||
} = process.env;
|
||||
|
||||
const s3Client = new S3Client({
|
||||
endpoint: S3_ENDPOINT,
|
||||
forcePathStyle: false,
|
||||
region: S3_REGION,
|
||||
credentials: {
|
||||
accessKeyId: S3_KEY,
|
||||
secretAccessKey: S3_SECRET
|
||||
},
|
||||
});
|
||||
|
||||
const name = FILE.split(`/`).at(-1);
|
||||
|
||||
const params = {
|
||||
Bucket: S3_BUCKET,
|
||||
Key: `${REPO}/${TAG}/${name}`,
|
||||
Body: createReadStream(FILE),
|
||||
ACL: "public-read",
|
||||
METADATA: {
|
||||
"x-repo-version": TAG,
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await s3Client.send(new PutObjectCommand(params));
|
||||
console.log("Upload successful");
|
||||
} catch (err) {
|
||||
console.error("Upload to s3 failed");
|
||||
};
|
||||
};
|
||||
|
||||
main();
|
||||
Loading…
Add table
Add a link
Reference in a new issue