diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d6b59e4 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,50 @@ +name: Build + +on: + push: + tags: + - 'v*' + - 'v*-prerelease' + - 'v*-dev' + - 'v*-rc*' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: '23' + + - name: Install Dependencies + run: npm install + + - name: Build app + run: npx electron-builder + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Mac x64 + if: matrix.os == 'macos-latest' + run: npx electron-builder --mac --x64 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ github.ref_name }} + files: | + dist/*.zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lintpretty.yml b/.github/workflows/lintpretty.yml new file mode 100644 index 0000000..93c5ad8 --- /dev/null +++ b/.github/workflows/lintpretty.yml @@ -0,0 +1,81 @@ +name: ESLint and Prettier + +on: + push: + branches: + - main + - dev + pull_request: + branches: + - main + - dev + +jobs: + lint_and_prettier: + runs-on: ubuntu-latest + + permissions: + contents: write # Ensure write permissions to push changes + + steps: + - name: Skip if commit is from workflow (prevents recursion) + if: startsWith(github.event.head_commit.message, 'WF:') # Skip workflow-triggered commits + run: | + echo "Skipping commit because it is a workflow-triggered commit" + exit 0 # Exit early to avoid committing changes again + + - name: Checkout repository + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} # Ensures the correct branch is checked out for PRs + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '23' # Set the Node.js version (you can change it as per your requirement) + + - name: Install dependencies + run: | + npm install + + - name: Run ESLint with auto-fix + run: | + npx eslint --fix . # Lint the code and automatically fix issues + + - name: Run Prettier + run: | + npx prettier --write '**/*.{js,json,html,css}' + + - name: Set up Git credentials + run: | + git config --global user.name "GitHub Actions" + git config --global user.email "actions@github.com" + + - name: Commit linted and prettified code with prefix + run: | + # Check if there are any changes + if [[ -n $(git status --porcelain) ]]; then + # There are changes, commit them + git config --global user.name "GitHub Actions" + git config --global user.email "actions@github.com" + + # Determine commit message based on event type + if [[ "${{ github.event_name }}" == "push" ]]; then + # For push events, use the commit message that triggered the push + ORIGINAL_COMMIT_MESSAGE="${{ github.event.head_commit.message }}" + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + # For PR events, use the PR title + ORIGINAL_COMMIT_MESSAGE="${{ github.event.pull_request.title }}" + fi + + # Create a commit message with a prefix and original commit message + COMMIT_MESSAGE="WF: Lint and Prettier: ${ORIGINAL_COMMIT_MESSAGE}" + + # Add changes and commit with the new message + git add . + git commit -m "$COMMIT_MESSAGE" + git push + else + # No changes, skip commit + echo "No changes to commit" + fi diff --git a/.gitignore b/.gitignore index e3c052b..b584e3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,3 @@ node_modules -.prettierignore -.prettierrc -eslint.config.mjs -buglist -featuremindstorm -lint.bat -pretty.bat \ No newline at end of file +dist +test \ No newline at end of file diff --git a/.hintrc b/.hintrc new file mode 100644 index 0000000..cf226eb --- /dev/null +++ b/.hintrc @@ -0,0 +1,10 @@ +{ + "extends": [ + "development" + ], + "hints": { + "compat-api/css": "off", + "no-inline-styles": "off", + "axe/text-alternatives": "off" + } +} \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..9a357a0 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +node_modules +.github \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..2912e49 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,21 @@ +{ + "arrowParens": "always", + "bracketSameLine": false, + "bracketSpacing": true, + "semi": true, + "experimentalTernaries": false, + "singleQuote": false, + "jsxSingleQuote": false, + "quoteProps": "as-needed", + "trailingComma": "none", + "singleAttributePerLine": false, + "htmlWhitespaceSensitivity": "css", + "vueIndentScriptAndStyle": false, + "proseWrap": "preserve", + "insertPragma": false, + "printWidth": 80, + "requirePragma": false, + "tabWidth": 2, + "useTabs": true, + "embeddedLanguageFormatting": "auto" +} diff --git a/TODOs b/TODOs new file mode 100644 index 0000000..8cb6d30 --- /dev/null +++ b/TODOs @@ -0,0 +1,10 @@ += for VERSION 1.0 = + Branding + Create README + +BUGS: + Blank lines counted as double at the end of the file + += for VERSION 1.1 = + Save last state of the editor upon close + Dynamic Skins diff --git a/electron-builder.json b/electron-builder.json new file mode 100644 index 0000000..dd4b363 --- /dev/null +++ b/electron-builder.json @@ -0,0 +1,28 @@ +{ + "appId": "com.speddy.webbox", + "productName": "webbox", + "directories": { + "output": "dist" + }, + "files": ["!filePresets/**", "!front/editor/highlighter.css"], + "extraResources": [ + { "from": "filePresets", "to": "../filePresets" }, + { + "from": "front/editor/highlighter.css", + "to": "../front/editor/highlighter.css" + } + ], + "icon": "resources/icon/icon.png", + "win": { + "target": "zip", + "artifactName": "webbox-${version}-win.zip" + }, + "mac": { + "target": "zip", + "artifactName": "webbox-${version}-mac-${arch}.zip" + }, + "linux": { + "target": "zip", + "artifactName": "webbox-${version}-linux.zip" + } +} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..27ede42 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,11 @@ +import globals from "globals"; +import pluginJs from "@eslint/js"; +import eslintConfigPrettier from "eslint-config-prettier"; + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + { files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } }, + { languageOptions: { globals: { ...globals.browser, ...globals.node } } }, + pluginJs.configs.recommended, + eslintConfigPrettier +]; diff --git a/front/editor/editor.css b/front/editor/editor.css index bb8ab6c..3d00019 100644 --- a/front/editor/editor.css +++ b/front/editor/editor.css @@ -18,6 +18,21 @@ body { width: calc(100% - 1%); box-sizing: border-box; border-radius: 5px; + scrollbar-width: thin; +} + +#FilePicker { + overflow-y: hidden; + overflow-x: auto; + height: 56px; + min-height: 56px; + max-height: 56px; +} + +#Controls { + height: 48px; + min-height: 48px; + max-height: 48px; } .fileDiv { @@ -83,7 +98,7 @@ button { color: black; padding: 5px 10px; border-radius: 5px; - border: 0px ridge black; + border: 1px ridge black; font-size: 16px; font-weight: bold; cursor: pointer; @@ -121,8 +136,7 @@ button:hover { overflow: hidden; white-space: pre; } - -textarea { +#TextArea { flex-grow: 1; background-color: rgb(32, 32, 32); color: white; @@ -133,7 +147,153 @@ textarea { border: none; outline: none; resize: none; - overflow-y: scroll; + overflow: auto; + scrollbar-width: thin; tab-size: 4; - white-space: pre; + white-space: pre; /* Prevent wrapping */ + word-wrap: normal; + min-height: 100px; /* Ensure it has height */ + box-sizing: border-box; + overflow-x: auto; /* Add horizontal scrollbar */ + overflow-y: auto; /* Add vertical scrollbar */ +} + +#saveDialog { + background-color: rgb(48, 48, 48); +} + +#saveDialogText { + font-family: Arial; + font-weight: bold; + color: white; + justify-content: center; +} + +.unsavedFile { + font-style: italic; +} + +.verticalLine { + border-left: 1px solid rgb(192, 192, 192); + height: 80%; +} + +h1, +h2 { + color: white; + font-family: "Arial"; +} + +h1 { + font-weight: bold; +} + +h2 { + font-weight: lighter; +} + +#noOpenedFileContainer { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; +} + +#noOpenedFileDialog { + text-align: center; + padding: 5px; +} + +/* New file dialog */ + +#newFileDialog, +#pickOpenedDisplay { + background-color: rgb(48, 48, 48); + border-radius: 5px; + padding: 1%; + gap: 10px; +} + +label { + color: white; + font-family: "Arial"; + font-weight: bold; + vertical-align: middle; +} + +textarea { + position: relative; + resize: none; + vertical-align: middle; + border: 1px solid black; + font-size: 16px; + height: 20px; + font-family: Arial; + width: calc(100% - 2%); + margin: 0.5% auto; + overflow: hidden; +} + +.containerDiv { + background-color: rgb(64, 64, 64); + border-radius: 5px; + padding: 1%; + display: flex; + flex-direction: row; + box-sizing: border-box; + gap: 10px; + align-items: center; +} + +.mainContainerDiv { + background-color: rgb(48, 48, 48); + padding: 1%; + border-radius: 5px; + gap: 10px; + display: flex; + flex-direction: column; + height: 100%; +} + +#fileDirLbl { + font-weight: normal; + font-size: 12; + text-wrap: wrap; + overflow-wrap: anywhere; +} + +button { + background-color: gray; + font-family: Arial; + color: black; + padding: 5px 10px; + border-radius: 5px; + border: 2px ridge black; + font-size: 16px; + font-weight: bold; + cursor: pointer; + transition: + background-color 0.3s ease, + color 0.3s ease; +} + +button:hover { + background-color: rgb(64, 64, 64); + color: white; +} + +#createFileBtnDiv { + display: flex; + align-items: center; + justify-content: center; + align-self: flex-end; + justify-self: center; + width: 100%; +} + +h3 { + color: white; + font-family: "Arial"; + font-weight: normal; } diff --git a/front/editor/editor.html b/front/editor/editor.html index a45fd6d..8797730 100644 --- a/front/editor/editor.html +++ b/front/editor/editor.html @@ -3,24 +3,80 @@
-