diff --git a/.circleci/config.yml b/.circleci/config.yml index 13d339892..38b3c8249 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,7 +27,7 @@ jobs: # fallback to using the latest cache if no exact match is found - v1-dependencies- - - node/install-npm + - run: sudo npm install -g npm@8.10.0 - node/install-packages: app-dir: ~/homebrewery cache-path: node_modules @@ -55,13 +55,13 @@ jobs: at: . # run tests! - - run: + - run: name: Test - Basic command: npm run test:basic - - run: + - run: name: Test - Mustache Spans command: npm run test:mustache-span - - run: + - run: name: Test - Routes command: npm run test:route @@ -71,4 +71,4 @@ workflows: - build - test: requires: - - build \ No newline at end of file + - build diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 05eda75b4..b87b267e6 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -12,10 +12,6 @@ body: description: The best feature requests provide an explanation of the current issue and then an explanation of how it could be improved. Screenshots/images can be pasted right in as well! validations: required: true - - type: checkboxes - id: terms + - type: markdown attributes: - label: "Please confirm:" - options: - - label: I have searched the Issues tracker for any duplicate requests and found none. - required: true \ No newline at end of file + value: "Please be sure to search for any close matches to your request in the GitHub Issues tracker before opening a new request, thanks!" diff --git a/.github/ISSUE_TEMPLATE/general_issue.yml b/.github/ISSUE_TEMPLATE/general_issue.yml index 33dd5b2bc..18c19254e 100644 --- a/.github/ISSUE_TEMPLATE/general_issue.yml +++ b/.github/ISSUE_TEMPLATE/general_issue.yml @@ -4,14 +4,15 @@ body: - type: markdown attributes: value: Please include as much information as possible. - - type: checkboxes + - type: dropdown id: renderer attributes: label: Renderer description: Which renderer does this issue occur on? If you are unsure, you can check the renderer in the Properties Editor (click the "i" in the Snippet Menu bar above the editor). options: - - label: Legacy - - label: v3 + - v3 + - Legacy + - Both validations: required: true - type: dropdown diff --git a/changelog.md b/changelog.md index 132b63d99..89b8a1976 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,6 @@ ```css h5 { font-size: .35cm !important; - margin-top: 0.3cm; } .page ul ul { @@ -45,6 +44,75 @@ pre { ## changelog For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery). + +### Monday 05/12/2022 - v3.4.1 +{{taskList + +##### G-Ambatte + +* [x] Fix Account page incorrect last login time + +Fixes issues [#2521](https://github.com/naturalcrit/homebrewery/issues/2521) + +##### Gazook + +* [x] Fix crashing on iOS and Safari browsers + +Fixes issues [#2531](https://github.com/naturalcrit/homebrewery/issues/2531) +}} + +### Monday 28/11/2022 - v3.4.0 +{{taskList + +##### G-Ambatte + +* [x] Fix for Chrome v108 handling of page size + +Fixes issues [#2445](https://github.com/naturalcrit/homebrewery/issues/2445), [#2516](https://github.com/naturalcrit/homebrewery/issues/2516) + +* [x] New account page with some user info, at {{openSans **USERNAME {{fa,fa-user}} → ACCOUNT {{fa,fa-user}}**}} + +Fixes issues [#2049](https://github.com/naturalcrit/homebrewery/issues/2049), [#2043](https://github.com/naturalcrit/homebrewery/issues/2043) + +* [x] Fix "Published/Private Brews" buttons on userpage + +Fixes issues [#2449](https://github.com/naturalcrit/homebrewery/issues/2449) + +##### Gazook + +* [x] Make autosave default on for new users + +* [x] Added link to our FAQ at {{openSans **NEED HELP? {{fa,fa-question-circle}} → FAQ {{fa,fa-question-circle}}**}} + +* [x] Fix curly blocks freezing with long property lists + +Fixes issues [#2393](https://github.com/naturalcrit/homebrewery/issues/2393) + +* [x] Items can now be removed from {{openSans **RECENT BREWS** {{fas,fa-history}} }} + +Fixes issues [#1918](https://github.com/naturalcrit/homebrewery/issues/1918) + +* [x] Curly injector syntax `{blue}` highlighting in editor + +Fixes issues [#1670](https://github.com/naturalcrit/homebrewery/issues/1670) + +}} + +### Thursday 28/10/2022 - v3.3.1 +{{taskList + +##### Calculuschild + +* [x] Fixes to several broken CSS styles from v3.3.0 + +Fixes issues [#2468](https://github.com/naturalcrit/homebrewery/issues/2468) + +##### Jeddai + +* [x] Reduce size of thumbnails on social media links + +}} + ### Friday 19/10/2022 - v3.3.0 {{taskList @@ -74,10 +142,12 @@ Fixes issues [#2135](https://github.com/naturalcrit/homebrewery/issues/2135) * [x] Fix brew settings being lost on first save Fixes issues [#2427](https://github.com/naturalcrit/homebrewery/issues/2427) +}} + +\column - - +{{taskList ##### Gazook: * [x] Several updates to bug reporting and error popups diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 07946c132..75ab08de4 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -137,9 +137,17 @@ const Editor = createClass({ codeMirror.addLineClass(lineNumber, 'text', 'columnSplit'); } + // Highlight injectors {style} + if(line.includes('{') && line.includes('}')){ + const regex = /(?:^|[^{\n])({(?=((?::(?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\2})/gm; + let match; + while ((match = regex.exec(line)) != null) { + codeMirror.markText({ line: lineNumber, ch: line.indexOf(match[1]) }, { line: lineNumber, ch: line.indexOf(match[1]) + match[1].length }, { className: 'injection' }); + } + } // Highlight inline spans {{content}} if(line.includes('{{') && line.includes('}}')){ - const regex = /{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])*\s*|}}/g; + const regex = /{{(?=((?::(?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\1 *|}}/g; let match; let blockCount = 0; while ((match = regex.exec(line)) != null) { @@ -158,7 +166,7 @@ const Editor = createClass({ // Highlight block divs {{\n Content \n}} let endCh = line.length+1; - const match = line.match(/^ *{{(?::(?:"[\w,\-()#%. ]*"|[\w\,\-()#%.]*)|[^"'{}\s])* *$|^ *}}$/); + const match = line.match(/^ *{{(?=((?::(?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':{}\s]*)*))\1 *$|^ *}}$/); if(match) endCh = match.index+match[0].length; codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' }); diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index 810ee1710..b8f978ba3 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -29,6 +29,10 @@ font-weight : bold; //font-style: italic; } + .injection{ + color : green; + font-weight : bold; + } } .brewJump{ diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 25b4daac8..ac644f1a1 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -9,11 +9,18 @@ const Nav = require('naturalcrit/nav/nav.jsx'); const StringArrayEditor = require('../stringArrayEditor/stringArrayEditor.jsx'); const Themes = require('themes/themes.json'); +const validations = require('./validations.js'); const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder']; const homebreweryThumbnail = require('../../thumbnail.png'); +const callIfExists = (val, fn, ...args)=>{ + if(val[fn]) { + val[fn](...args); + } +}; + const MetadataEditor = createClass({ displayName : 'MetadataEditor', getDefaultProps : function() { @@ -22,6 +29,7 @@ const MetadataEditor = createClass({ editId : null, title : '', description : '', + thumbnail : '', tags : [], published : false, authors : [], @@ -51,11 +59,27 @@ const MetadataEditor = createClass({ }, handleFieldChange : function(name, e){ - this.props.onChange({ - ...this.props.metadata, - [name] : e.target.value - }); + // load validation rules, and check input value against them + const inputRules = validations[name] ?? []; + const validationErr = inputRules.map((rule)=>rule(e.target.value)).filter(Boolean); + + // if no validation rules, save to props + if(validationErr.length === 0){ + callIfExists(e.target, 'setCustomValidity', ''); + this.props.onChange({ + ...this.props.metadata, + [name] : e.target.value + }); + } else { + // if validation issues, display built-in browser error popup with each error. + const errMessage = validationErr.map((err)=>{ + return `- ${err}`; + }).join('\n'); + callIfExists(e.target, 'setCustomValidity', errMessage); + callIfExists(e.target, 'reportValidity'); + } }, + handleSystem : function(system, e){ if(e.target.checked){ this.props.metadata.systems.push(system); @@ -64,6 +88,7 @@ const MetadataEditor = createClass({ } this.props.onChange(this.props.metadata); }, + handleRenderer : function(renderer, e){ if(e.target.checked){ this.props.metadata.renderer = renderer; @@ -228,21 +253,21 @@ const MetadataEditor = createClass({
this.handleFieldChange('title', e)} />
-