0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-23 20:53:05 +00:00

Compare commits

..

1822 Commits

Author SHA1 Message Date
Trevor Buckner
c7d94b0779 Small cleanup 2024-12-08 23:59:27 -05:00
Trevor Buckner
9758797e2b If user is owner, fetch Google Brew with user auth
Fixes the case where a user can see a Google Brew under their account (`listBrew()` uses their personal auth) but can't actually delete it (`getBrew()`  only uses the serviceAccount). Occurs if a Google brew has lost its permissions somehow (set to "restricted", etc.) such that serviceAccount can no longer interact with it.
2024-12-08 23:42:14 -05:00
Trevor Buckner
74a7983757 Refactor and clean up "getBrew()"
Some redundant logic and sprawling formatting
2024-12-08 23:39:26 -05:00
Trevor Buckner
a62d2bd457 Merge pull request #3937 from naturalcrit/dependabot/npm_and_yarn/express-4.21.2
Bump express from 4.21.1 to 4.21.2
2024-12-06 16:30:42 -05:00
dependabot[bot]
ffa9666bb9 Bump express from 4.21.1 to 4.21.2
Bumps [express](https://github.com/expressjs/express) from 4.21.1 to 4.21.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.2/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.1...4.21.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-06 21:29:54 +00:00
Trevor Buckner
ed404d3906 Merge pull request #3935 from naturalcrit/dependabot/npm_and_yarn/babel/preset-react-7.26.3
Bump @babel/preset-react from 7.25.9 to 7.26.3
2024-12-06 16:28:35 -05:00
dependabot[bot]
14a0f79ac8 Bump @babel/preset-react from 7.25.9 to 7.26.3
Bumps [@babel/preset-react](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react) from 7.25.9 to 7.26.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.3/packages/babel-preset-react)

---
updated-dependencies:
- dependency-name: "@babel/preset-react"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-05 03:16:54 +00:00
Trevor Buckner
136a6d4024 Merge pull request #3930 from naturalcrit/dependabot/npm_and_yarn/globals-15.13.0
Bump globals from 15.12.0 to 15.13.0
2024-12-03 20:43:13 -05:00
Trevor Buckner
737e27f062 Merge pull request #3934 from 5e-Cleric/fix-buttons
Fix Vault styles
2024-12-03 20:42:54 -05:00
Víctor Losada Hernández
ee9143fa35 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into fix-buttons 2024-12-03 20:20:42 +01:00
Víctor Losada Hernández
c62bb53660 turn back checkboxes to default, fix button styles and filter bar to correct font. 2024-12-03 20:16:42 +01:00
dependabot[bot]
4e5a971f0a Bump globals from 15.12.0 to 15.13.0
Bumps [globals](https://github.com/sindresorhus/globals) from 15.12.0 to 15.13.0.
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v15.12.0...v15.13.0)

---
updated-dependencies:
- dependency-name: globals
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-02 22:22:41 +00:00
Trevor Buckner
16184f1b8d Merge pull request #3916 from naturalcrit/dependabot/npm_and_yarn/nanoid-5.0.9
Bump nanoid from 5.0.8 to 5.0.9
2024-12-02 17:21:22 -05:00
dependabot[bot]
23bd0309b9 Bump nanoid from 5.0.8 to 5.0.9
Bumps [nanoid](https://github.com/ai/nanoid) from 5.0.8 to 5.0.9.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/5.0.8...5.0.9)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-02 22:17:58 +00:00
Trevor Buckner
20dba6b7b3 Merge pull request #3929 from naturalcrit/dependabot/npm_and_yarn/eslint-9.16.0
Bump eslint from 9.15.0 to 9.16.0
2024-12-02 17:15:55 -05:00
dependabot[bot]
5177c9a64e Bump eslint from 9.15.0 to 9.16.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.15.0 to 9.16.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.15.0...v9.16.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-02 22:04:50 +00:00
Trevor Buckner
d179c18c35 Merge pull request #3928 from naturalcrit/dependabot/npm_and_yarn/dompurify-3.2.2
Bump dompurify from 3.2.1 to 3.2.2
2024-12-02 17:03:16 -05:00
dependabot[bot]
6e4e35c7ad Bump dompurify from 3.2.1 to 3.2.2
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.2.1...3.2.2)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-02 17:27:52 +00:00
Trevor Buckner
6c2721d49f Merge pull request #3924 from naturalcrit/dependabot/npm_and_yarn/stylelint-16.11.0
Bump stylelint from 16.10.0 to 16.11.0
2024-12-02 12:26:19 -05:00
Trevor Buckner
029d61b6ad Merge branch 'master' into dependabot/npm_and_yarn/stylelint-16.11.0 2024-12-02 12:25:48 -05:00
Trevor Buckner
f58040e9a4 Merge pull request #3931 from G-Ambatte/tagsToArrayOnLoad-#3927
Convert any `tags` strings to arrays
2024-12-02 12:25:05 -05:00
Trevor Buckner
9f9948f531 Add comment 2024-12-02 12:23:54 -05:00
G.Ambatte
2743ab869a Merge branch 'master' into tagsToArrayOnLoad-#3927 2024-12-02 17:17:35 +13:00
G.Ambatte
4b21538e3e Add splitTextStyleAndMetadata tests 2024-12-02 17:14:45 +13:00
G.Ambatte
e17db0788c Convert any tags strings to arrays 2024-12-02 16:18:18 +13:00
Trevor Buckner
bea74c3b46 Merge pull request #3926 from dbolack-ab/Issue_3919
Implement Gazook89's suggested fix for missing Page Shadows
2024-12-01 20:57:57 -05:00
David Bolack
e252a39bd2 Implement Gazook89's suggested fix 2024-12-01 11:41:29 -06:00
dependabot[bot]
7ef259ddbe Bump stylelint from 16.10.0 to 16.11.0
Bumps [stylelint](https://github.com/stylelint/stylelint) from 16.10.0 to 16.11.0.
- [Release notes](https://github.com/stylelint/stylelint/releases)
- [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint/stylelint/compare/16.10.0...16.11.0)

---
updated-dependencies:
- dependency-name: stylelint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-30 17:40:38 +00:00
Trevor Buckner
d18005fad4 Merge pull request #3915 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.8.3
Bump mongoose from 8.8.2 to 8.8.3
2024-11-30 12:39:20 -05:00
Trevor Buckner
86402cdbc8 Merge pull request #3920 from 5e-Cleric/changelog-v3.17.0
v3.16.1 FaQ fix
2024-11-30 12:38:46 -05:00
Trevor Buckner
e28b4e8c20 Merge pull request #3921 from 5e-Cleric/add-vault-to-more-navs
add vault navitem to share and edit pages
2024-11-27 17:50:12 -05:00
Víctor Losada Hernández
7c09680939 add vault navitem to share and edit pages 2024-11-27 23:45:25 +01:00
Víctor Losada Hernández
3f0a6a577f faq new version 2024-11-27 23:28:08 +01:00
dependabot[bot]
6f4cc0d91b Bump mongoose from 8.8.2 to 8.8.3
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.8.2 to 8.8.3.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.8.2...8.8.3)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-27 21:29:38 +00:00
Trevor Buckner
e711a1c207 Merge pull request #3917 from naturalcrit/v3.16.1
Version 3.16.1
2024-11-27 16:28:20 -05:00
Trevor Buckner
add088c2a9 Up version to 3.16.1 2024-11-27 16:26:26 -05:00
Trevor Buckner
6d8415bfeb Merge pull request #3911 from dbolack-ab/autoESM
Fix regression in emoji auto-complete due to ESM update
2024-11-25 12:11:38 -05:00
David Bolack
decb334808 Fix regression in emoji auto-complete due to ESM update 2024-11-25 10:41:11 -06:00
Trevor Buckner
66f71972eb Merge pull request #3860 from naturalcrit/dependabot/npm_and_yarn/nanoid-5.0.8
Bump nanoid from 3.3.4 to 5.0.8
2024-11-21 13:36:36 -05:00
Trevor Buckner
ebe8e1067c Move babel config to separate file
Jest struggles to read all babel configurations if directly inside package.json.

This now allows us to install nanoid 5 and pass all tests with it.
2024-11-21 13:33:32 -05:00
dependabot[bot]
9807cf762b Bump nanoid from 3.3.4 to 5.0.8
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.4 to 5.0.8.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.4...5.0.8)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-21 16:51:39 +00:00
Trevor Buckner
b58563cb42 Merge pull request #3897 from naturalcrit/dependabot/npm_and_yarn/eslint-9.15.0
Bump eslint from 9.14.0 to 9.15.0
2024-11-21 11:37:22 -05:00
dependabot[bot]
7c3f3b87af Bump eslint from 9.14.0 to 9.15.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.14.0 to 9.15.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.14.0...v9.15.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-21 16:32:02 +00:00
Trevor Buckner
e7daad592c Merge pull request #3859 from naturalcrit/dependabot/npm_and_yarn/elliptic-6.6.0
Bump elliptic from 6.5.7 to 6.6.0
2024-11-21 11:30:40 -05:00
Trevor Buckner
992359e239 Merge branch 'master' into dependabot/npm_and_yarn/elliptic-6.6.0 2024-11-21 11:27:47 -05:00
Trevor Buckner
b2546f3458 Merge pull request #3903 from naturalcrit/dependabot/npm_and_yarn/dompurify-3.2.1
Bump dompurify from 3.2.0 to 3.2.1
2024-11-21 11:27:32 -05:00
dependabot[bot]
6f016bf5b6 Bump dompurify from 3.2.0 to 3.2.1
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.2.0...3.2.1)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-21 16:25:09 +00:00
Trevor Buckner
7cd3c69fbd Merge pull request #3898 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.8.2
Bump mongoose from 8.8.1 to 8.8.2
2024-11-21 11:23:50 -05:00
Trevor Buckner
9b1507d4f5 Merge branch 'master' into dependabot/npm_and_yarn/mongoose-8.8.2 2024-11-21 11:21:55 -05:00
Trevor Buckner
2e49bf4fa8 Merge pull request #3902 from naturalcrit/updateToES6Modules
Upgrade server-side code to ESM (import vs require)
2024-11-21 11:21:21 -05:00
Trevor Buckner
e5624434d6 Update buildAdmin.js 2024-11-20 17:04:23 -05:00
Trevor Buckner
1850173f87 Remove unused dependency 2024-11-20 16:22:48 -05:00
Trevor Buckner
fb9148ada5 Site runs and all tests pass 2024-11-20 16:21:35 -05:00
dependabot[bot]
b857a91ab8 Bump mongoose from 8.8.1 to 8.8.2
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.8.1 to 8.8.2.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.8.1...8.8.2)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-19 03:21:50 +00:00
Trevor Buckner
b7c49218ae Merge pull request #3735 from Gazook89/Functional-Tag-Editor
TagInput - Functional component for tag-like inputs
2024-11-13 13:58:42 -05:00
Trevor Buckner
f4d4334a75 Merge branch 'master' into Functional-Tag-Editor 2024-11-13 13:52:01 -05:00
Víctor Losada Hernández
38b4c285a3 Merge pull request #3890 from Gazook89/Update-core-and-reset
Update Core.less and reset.less
2024-11-12 22:09:16 +01:00
Víctor Losada Hernández
cf46a975aa Merge branch 'master' into Update-core-and-reset 2024-11-12 22:05:27 +01:00
Trevor Buckner
9f693547f7 Merge pull request #3889 from naturalcrit/dependabot/npm_and_yarn/express-static-gzip-2.2.0
Bump express-static-gzip from 2.1.8 to 2.2.0
2024-11-12 13:27:28 -05:00
Trevor Buckner
a69dd998f5 Merge branch 'master' into dependabot/npm_and_yarn/express-static-gzip-2.2.0 2024-11-12 13:16:34 -05:00
Trevor Buckner
f141515446 Merge pull request #3888 from naturalcrit/dependabot/npm_and_yarn/marked-emoji-1.4.3
Bump marked-emoji from 1.4.2 to 1.4.3
2024-11-12 13:16:23 -05:00
dependabot[bot]
f749706cb3 Bump marked-emoji from 1.4.2 to 1.4.3
Bumps [marked-emoji](https://github.com/UziTech/marked-emoji) from 1.4.2 to 1.4.3.
- [Release notes](https://github.com/UziTech/marked-emoji/releases)
- [Changelog](https://github.com/UziTech/marked-emoji/blob/main/release.config.cjs)
- [Commits](https://github.com/UziTech/marked-emoji/compare/v1.4.2...v1.4.3)

---
updated-dependencies:
- dependency-name: marked-emoji
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-12 18:15:37 +00:00
dependabot[bot]
b22f3d041c Bump express-static-gzip from 2.1.8 to 2.2.0
Bumps [express-static-gzip](https://github.com/tkoenig89/express-static-gzip) from 2.1.8 to 2.2.0.
- [Release notes](https://github.com/tkoenig89/express-static-gzip/releases)
- [Commits](https://github.com/tkoenig89/express-static-gzip/compare/v2.1.8...v2.2.0)

---
updated-dependencies:
- dependency-name: express-static-gzip
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-12 18:15:31 +00:00
Trevor Buckner
dd8692d82b Merge pull request #3887 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.8.1
Bump mongoose from 8.7.3 to 8.8.1
2024-11-12 13:14:11 -05:00
dependabot[bot]
0d2dfe66bc Bump mongoose from 8.7.3 to 8.8.1
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.7.3 to 8.8.1.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.7.3...8.8.1)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-12 05:36:16 +00:00
Trevor Buckner
0437635861 Merge pull request #3892 from naturalcrit/dependabot/npm_and_yarn/dompurify-3.2.0
Bump dompurify from 3.1.7 to 3.2.0
2024-11-12 00:35:00 -05:00
Trevor Buckner
a5f12ca0b4 Merge branch 'master' into dependabot/npm_and_yarn/dompurify-3.2.0 2024-11-12 00:27:07 -05:00
Trevor Buckner
07e0a7c1b5 Merge pull request #3820 from G-Ambatte/addAdminFixScriptTool-#3801
Add script fix tool to Admin page #3801
2024-11-12 00:21:05 -05:00
Trevor Buckner
2e9c7b1d9b Shorten label 2024-11-12 00:20:37 -05:00
Trevor Buckner
0ddc3ae5b9 Merge branch 'master' into addAdminFixScriptTool-#3801 2024-11-12 00:16:07 -05:00
Trevor Buckner
8c6c8f861d Automatically re-check for scripts
Adding a separate `keepText` field for the `updateBrew()` API might be a bandaid for something that should be looked at more deeply as a separate refactor, considering `updateBrew()` is configured to just return the stub and not the whole document.

For now, re-scanning for script tags after updating can be as simple as just re-looking up the brew.
2024-11-12 00:08:56 -05:00
dependabot[bot]
107aa34ee4 Bump dompurify from 3.1.7 to 3.2.0
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.1.7 to 3.2.0.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.1.7...3.2.0)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-12 03:12:02 +00:00
Trevor Buckner
e006826e3e Merge pull request #3891 from dbolack-ab/Issue_3718
Fix Issue 3718 by bounds checking prerender.
2024-11-11 22:04:36 -05:00
David Bolack
4e4463fe4d Fix Issue 3718 by bounds checking prerender. 2024-11-11 11:17:00 -06:00
Gazook89
1a56c393ab Merge branch 'master' into Update-core-and-reset 2024-11-10 21:50:03 -06:00
Gazook89
9bc4b1fb56 Changes to core.less, reset.less, and toolbar
Making some changes to the reset.less so that some default UA button styling is removed.

Then, changing core.less so that the classic "HB" button styling is scoped to a certain class `.colorButton`.  This will make it easier to use the button element in other places.
2024-11-10 21:48:01 -06:00
Gazook89
234d484a74 Merge remote-tracking branch 'upstream/master' 2024-11-10 15:55:54 -06:00
G.Ambatte
dc1d40512b Reinstate length check 2024-11-10 21:45:17 +13:00
G.Ambatte
2dafbf2080 Simplify Admin brew lookup function 2024-11-10 20:19:30 +13:00
G.Ambatte
033b7fa44f Lint fix 2024-11-10 19:35:57 +13:00
G.Ambatte
2c4f705072 Merge branch 'addAdminFixScriptTool-#3801' of https://github.com/G-Ambatte/homebrewery into addAdminFixScriptTool-#3801 2024-11-10 19:34:25 +13:00
G.Ambatte
ee811e94e1 Remove error handling that can never trigger 2024-11-10 19:34:19 +13:00
G.Ambatte
fcae147723 Merge branch 'master' into addAdminFixScriptTool-#3801 2024-11-10 19:34:17 +13:00
G.Ambatte
b3793a3330 Simplify scriptCount logic 2024-11-10 19:30:57 +13:00
G.Ambatte
952b67aed3 Remove checkForScript state 2024-11-10 19:29:28 +13:00
G.Ambatte
27f14b042b Remove comment about irrelevant tag cleaning 2024-11-10 19:24:54 +13:00
G.Ambatte
49d30007d3 Merge branch 'addAdminFixScriptTool-#3801' of https://github.com/G-Ambatte/homebrewery into addAdminFixScriptTool-#3801 2024-11-10 19:23:47 +13:00
G.Ambatte
bd26f02ddb Remove getBrew admin regex search 2024-11-10 19:23:42 +13:00
Trevor Buckner
ccc37fc0d5 Merge pull request #3873 from naturalcrit/dependabot/npm_and_yarn/globals-15.12.0
Bump globals from 15.11.0 to 15.12.0
2024-11-10 01:15:53 -05:00
dependabot[bot]
9973999e86 Bump globals from 15.11.0 to 15.12.0
Bumps [globals](https://github.com/sindresorhus/globals) from 15.11.0 to 15.12.0.
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v15.11.0...v15.12.0)

---
updated-dependencies:
- dependency-name: globals
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-10 06:14:56 +00:00
Trevor Buckner
2aec54748a Merge pull request #3871 from naturalcrit/dependabot/npm_and_yarn/eslint-9.14.0
Bump eslint from 9.13.0 to 9.14.0
2024-11-10 01:13:42 -05:00
dependabot[bot]
5585c27cb8 Bump eslint from 9.13.0 to 9.14.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.13.0 to 9.14.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.13.0...v9.14.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-10 06:11:39 +00:00
Trevor Buckner
52ae343309 Merge pull request #3881 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-jest-28.9.0
Bump eslint-plugin-jest from 28.8.3 to 28.9.0
2024-11-10 01:10:26 -05:00
dependabot[bot]
f8d60fc4da Bump eslint-plugin-jest from 28.8.3 to 28.9.0
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 28.8.3 to 28.9.0.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.8.3...v28.9.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-10 06:08:20 +00:00
Trevor Buckner
69e827a663 Merge pull request #3882 from naturalcrit/dependabot/npm_and_yarn/react-router-dom-6.28.0
Bump react-router-dom from 6.27.0 to 6.28.0
2024-11-10 01:06:58 -05:00
Trevor Buckner
d1d73023a2 Merge branch 'master' into dependabot/npm_and_yarn/react-router-dom-6.28.0 2024-11-10 00:55:34 -05:00
Trevor Buckner
f4af19ed81 Merge pull request #3885 from Gazook89/Fix-dialog.jsx
Fix Dialog.jsx to prevent crashes
2024-11-10 00:06:39 -05:00
Gazook89
bc5a9c9039 lint 2024-11-08 21:57:13 -06:00
Gazook89
f7dfedcd44 give dismisskeys a default 2024-11-08 21:57:13 -06:00
Gazook89
b7b1981bde lint 2024-11-08 21:56:45 -06:00
Gazook89
2e8368d08c give dismisskeys a default 2024-11-08 21:56:35 -06:00
G.Ambatte
c6b0b6a0ea Merge branch 'master' into addAdminFixScriptTool-#3801 2024-11-07 23:31:04 +13:00
dependabot[bot]
7c7326b42a Bump react-router-dom from 6.27.0 to 6.28.0
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.27.0 to 6.28.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/react-router-dom@6.28.0/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.28.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-07 03:42:03 +00:00
Trevor Buckner
d0cf6eebbb Merge pull request #3869 from 5e-Cleric/fix-splitpane-overflowing-page
Fix-splitpane-overflowing-page
2024-11-05 16:43:59 -05:00
Trevor Buckner
0ba838f5ae Merge pull request #3880 from Gazook89/fix-memoization
Fix Memoization
2024-11-05 13:51:48 -05:00
Gazook89
172a3eaadf fix memoization on brewRenderer.jsx 2024-11-05 12:45:41 -06:00
Trevor Buckner
b868ba9406 Merge pull request #3799 from Gazook89/View-Modes
View Modes - Single / Facing Pages / "Flow" arrangements
2024-11-04 16:05:53 -05:00
Gazook89
89a16956b9 Merge branch 'master' into View-Modes 2024-11-04 14:22:54 -06:00
Gazook89
b098d28407 linting 2024-11-04 14:08:06 -06:00
Gazook89
1be1b3b747 small accessibility changes. 2024-11-04 13:55:18 -06:00
Trevor Buckner
f63d2de8f4 Refactor toolbar view options (#2)
* Refactor toolbar view options

* Remove a couple more unused states
2024-11-01 22:19:48 -05:00
Víctor Losada Hernández
626b602a61 last fix 2024-11-01 20:39:45 +01:00
Víctor Losada Hernández
3d7d90104b revert content deletion 2024-11-01 20:37:28 +01:00
G.Ambatte
422fd7bb57 Merge branch 'master' into addAdminFixScriptTool-#3801 2024-10-30 12:01:42 +13:00
Trevor Buckner
c7c8dafb18 Merge pull request #3816 from G-Ambatte/refactorVersionHistory
Refactor version history to use custom store wrapper
2024-10-29 17:10:22 -04:00
G.Ambatte
ea25ae625a Merge branch 'refactorVersionHistory' of https://github.com/G-Ambatte/homebrewery into refactorVersionHistory 2024-10-30 08:21:56 +13:00
G.Ambatte
ebf900ba24 Remove Proxy version 2024-10-30 08:21:51 +13:00
G.Ambatte
0037c91cc5 Merge branch 'master' into refactorVersionHistory 2024-10-30 08:10:47 +13:00
Trevor Buckner
8a8bf883e6 Merge pull request #3548 from G-Ambatte/fixLinks-#3547
Improve HTML sanitization
2024-10-29 14:20:50 -04:00
Trevor Buckner
17539cb80b Merge branch 'master' into fixLinks-#3547 2024-10-29 14:15:02 -04:00
Trevor Buckner
bb057ba057 Merge pull request #3861 from 5e-Cleric/vault-styles-quickfix
Vault styles quickfix
2024-10-29 14:01:57 -04:00
Trevor Buckner
99ad865311 Merge branch 'master' into vault-styles-quickfix 2024-10-29 13:45:30 -04:00
Víctor Losada Hernández
48baaa33e2 linting 2024-10-29 14:22:51 +01:00
Víctor Losada Hernández
6f07d25101 second fix 2024-10-29 14:20:49 +01:00
Víctor Losada Hernández
fec904b4c6 initial commit 2024-10-29 14:16:45 +01:00
G.Ambatte
a29aca32e7 Display createdAt time 2024-10-29 20:42:53 +13:00
G.Ambatte
6fed42198d Simplify initCustomStore 2024-10-29 19:30:22 +13:00
G.Ambatte
446406758f Merge branch 'master' into refactorVersionHistory 2024-10-29 19:12:59 +13:00
G.Ambatte
2d9da23c25 Merge branch 'master' into addAdminFixScriptTool-#3801 2024-10-29 19:08:49 +13:00
G.Ambatte
b24c9daa08 Update HTML test 2024-10-29 18:15:46 +13:00
G.Ambatte
f5bc490380 Remove type='submit' attribute 2024-10-29 18:10:25 +13:00
G.Ambatte
4673303bc2 Remove unused JSDom package 2024-10-29 17:41:16 +13:00
G.Ambatte
e550ab4046 Remove eslint override from HTML tests 2024-10-29 17:40:55 +13:00
G.Ambatte
be4ba06081 Removed unused themes.json import 2024-10-29 17:32:31 +13:00
G.Ambatte
0fda0673b2 Simplify logic & reduce nesting 2024-10-29 17:27:59 +13:00
G.Ambatte
9edf65c252 Shift to element.remove() 2024-10-29 16:50:44 +13:00
G.Ambatte
3f8ec30f89 Fix broken check for document existence 2024-10-29 16:50:33 +13:00
G.Ambatte
f1bebe3895 Move import to be adjacent to existing requires 2024-10-29 16:36:49 +13:00
G.Ambatte
f5954b03f2 Add comment to reference vue-html-secure pacakge 2024-10-29 16:34:50 +13:00
G.Ambatte
a265723c57 Merge branch 'master' into fixLinks-#3547 2024-10-29 16:32:23 +13:00
Trevor Buckner
ca90e1804a Merge branch 'master' into dependabot/npm_and_yarn/elliptic-6.6.0 2024-10-28 23:26:39 -04:00
Trevor Buckner
e7c0cdae3d Merge pull request #3858 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.7.3
Bump mongoose from 8.7.2 to 8.7.3
2024-10-28 23:26:25 -04:00
dependabot[bot]
db75e0dd66 Bump elliptic from 6.5.7 to 6.6.0
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.7 to 6.6.0.
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.7...v6.6.0)

---
updated-dependencies:
- dependency-name: elliptic
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-29 03:25:59 +00:00
Trevor Buckner
56d024a2e6 Merge branch 'master' into dependabot/npm_and_yarn/mongoose-8.7.3 2024-10-28 23:25:45 -04:00
Trevor Buckner
f6ed348824 Merge pull request #3857 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.26.0
Bump @babel/preset-env from 7.25.9 to 7.26.0
2024-10-28 23:25:34 -04:00
Trevor Buckner
a4406d953a Merge branch 'master' into dependabot/npm_and_yarn/babel/preset-env-7.26.0 2024-10-28 23:25:05 -04:00
Trevor Buckner
1a41252d70 Merge pull request #3856 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.26.0
Bump @babel/core from 7.25.9 to 7.26.0
2024-10-28 23:24:54 -04:00
Trevor Buckner
97371be26a Merge branch 'master' into dependabot/npm_and_yarn/babel/core-7.26.0 2024-10-28 23:23:08 -04:00
Trevor Buckner
994fbd197a Merge pull request #3855 from 5e-Cleric/refactor-splitpane
Refactor splitpane as a functional component
2024-10-28 15:00:39 -04:00
dependabot[bot]
4995aebb93 Bump mongoose from 8.7.2 to 8.7.3
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.7.2 to 8.7.3.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.7.2...8.7.3)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 03:24:31 +00:00
dependabot[bot]
782fa3a2a0 Bump @babel/preset-env from 7.25.9 to 7.26.0
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.25.9 to 7.26.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.0/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 03:24:06 +00:00
dependabot[bot]
5f71d2902b Bump @babel/core from 7.25.9 to 7.26.0
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.25.9 to 7.26.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.0/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 03:23:52 +00:00
Víctor Losada Hernández
391d0a0bfe remove flickering in divider 2024-10-27 10:20:49 +01:00
Víctor Losada Hernández
782ee7a4ad Merge branch 'master' of https://github.com/naturalcrit/homebrewery into refactor-splitpane 2024-10-27 10:14:30 +01:00
Víctor Losada Hernández
987063422d use storage instead of state to correctly save position while resizing 2024-10-27 10:13:59 +01:00
Trevor Buckner
26afb67f61 Merge pull request #3823 from 5e-Cleric/erase-unnecessary-divs
Clean up DOM
2024-10-26 23:06:17 -04:00
Trevor Buckner
d2f6bc03db Merge branch 'master' into erase-unnecessary-divs 2024-10-26 23:02:40 -04:00
Trevor Buckner
547bedb5f9 Merge pull request #3851 from 5e-Cleric/userpage-to-func-comp
Refactor UserPage as a functional component
2024-10-26 23:00:18 -04:00
Trevor Buckner
1b4d41fc19 Remove error prop
Userpage is never passed `Error` prop from anywhere. Thus we can rename the error state here from `currentError` to just `error`
2024-10-26 22:59:49 -04:00
Trevor Buckner
6f2252635a Fix crash; props need props.var to work 2024-10-26 22:56:29 -04:00
Víctor Losada Hernández
46eac41021 further formatting 2024-10-26 23:03:25 +02:00
Víctor Losada Hernández
43441f3185 last changes as suggested 2024-10-26 22:54:16 +02:00
Víctor Losada Hernández
f2765650f7 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into userpage-to-func-comp 2024-10-26 19:46:55 +02:00
Víctor Losada Hernández
a017c28b02 allow for null error instead of undefined 2024-10-26 19:45:55 +02:00
Víctor Losada Hernández
ef1e0f1faa destructure props as per usual 2024-10-26 19:45:26 +02:00
Víctor Losada Hernández
5dc961505b Merge branch 'userpage-to-func-comp' of https://github.com/5e-Cleric/homebrewery into userpage-to-func-comp 2024-10-26 19:44:08 +02:00
Víctor Losada Hernández
b129ec1469 linting 2024-10-26 19:43:27 +02:00
Víctor Losada Hernández
adcbd7c4c8 Merge branch 'master' into erase-unnecessary-divs 2024-10-26 18:18:49 +02:00
Víctor Losada Hernández
843aa6d769 linting and final pass 2024-10-26 16:45:33 +02:00
Víctor Losada Hernández
8ab9b842fc Merge branch 'master' of https://github.com/naturalcrit/homebrewery into refactor-splitpane 2024-10-26 16:29:08 +02:00
Víctor Losada Hernández
f8b5a8133e initial commit 2024-10-26 16:15:53 +02:00
G.Ambatte
478a541d62 Remove wrapper from file name 2024-10-26 09:58:09 +13:00
G.Ambatte
eb852b8045 Add IDB Proxy 2024-10-26 09:50:07 +13:00
G.Ambatte
07e7f3e70c Merge branch 'master' into refactorVersionHistory 2024-10-25 20:54:34 +13:00
G.Ambatte
fea8f157a7 Change script clean to use Homebrew API update 2024-10-25 17:45:12 +13:00
G.Ambatte
898be28af3 Fix Homebrew API parameter 2024-10-25 11:40:17 +13:00
G.Ambatte
63f6f6d3c6 Fix new getBrew access type 2024-10-25 11:27:28 +13:00
G.Ambatte
ac2de613c5 Change Admin lookup to use Homebrew.API getBrew instead 2024-10-25 11:19:55 +13:00
G.Ambatte
948f03b5b8 Add admin access type to getBrew 2024-10-25 11:18:36 +13:00
G.Ambatte
28894adeab Add error check for no brew found 2024-10-25 11:17:44 +13:00
Víctor Losada Hernández
9770fea3fd update navitems call as suggested
Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
2024-10-24 21:13:49 +02:00
Víctor Losada Hernández
422257743e accept navitems suggestion
Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
2024-10-24 20:39:59 +02:00
G.Ambatte
e3619bb1fc Add global flag to regex 2024-10-25 00:11:02 +13:00
G.Ambatte
db1fdca3ab Automatically check for SCRIPT tags 2024-10-24 20:45:12 +13:00
G.Ambatte
c2f56833f3 Merge branch 'addAdminFixScriptTool-#3801' of https://github.com/G-Ambatte/homebrewery into addAdminFixScriptTool-#3801 2024-10-24 17:21:00 +13:00
G.Ambatte
d3cc5c890b Display number of SCRIPT tags detected in brew 2024-10-24 17:20:55 +13:00
G.Ambatte
8eac8eff4b Merge branch 'master' into addAdminFixScriptTool-#3801 2024-10-24 16:22:29 +13:00
Trevor Buckner
8bede8f0ee Merge pull request #3853 from 5e-Cleric/fix-snippetbar-behaviour
fix snippetbar weirdness
2024-10-23 22:45:39 -04:00
Víctor Losada Hernández
c7894499b1 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into fix-snippetbar-behaviour 2024-10-24 01:25:15 +02:00
Víctor Losada Hernández
55a50ce261 always stretch 2024-10-24 01:23:26 +02:00
Víctor Losada Hernández
5b675918ad real fix for the meta tab 2024-10-24 01:10:47 +02:00
Víctor Losada Hernández
70046e00f8 fix min-width in meta tab 2024-10-24 01:07:52 +02:00
Víctor Losada Hernández
e129eb2f5d Merge branch 'fix-snippetbar-behaviour' of https://github.com/5e-Cleric/homebrewery into fix-snippetbar-behaviour 2024-10-24 01:04:23 +02:00
Víctor Losada Hernández
56c9413ab5 next iteration 2024-10-24 01:04:22 +02:00
Trevor Buckner
671044ca3a Merge pull request #3850 from naturalcrit/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.25.9
Bump @babel/plugin-transform-runtime from 7.25.7 to 7.25.9
2024-10-23 17:02:34 -04:00
Víctor Losada Hernández
04baabc27d Merge branch 'master' into addAdminFixScriptTool-#3801 2024-10-23 21:25:36 +02:00
dependabot[bot]
4add67086d Bump @babel/plugin-transform-runtime from 7.25.7 to 7.25.9
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.25.7 to 7.25.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.9/packages/babel-plugin-transform-runtime)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-23 19:24:33 +00:00
Víctor Losada Hernández
66451a3b1e Merge branch 'master' into refactorVersionHistory 2024-10-23 21:24:21 +02:00
Trevor Buckner
785041dcd1 Merge pull request #3848 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.25.9
Bump @babel/preset-env from 7.25.8 to 7.25.9
2024-10-23 15:23:39 -04:00
Trevor Buckner
40bb823efa Merge branch 'master' into dependabot/npm_and_yarn/babel/preset-env-7.25.9 2024-10-23 15:22:51 -04:00
dependabot[bot]
0dd5b262f7 Bump @babel/preset-env from 7.25.8 to 7.25.9
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.25.8 to 7.25.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.9/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-23 19:22:44 +00:00
Trevor Buckner
2ed6aad6f7 Merge pull request #3849 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.25.9
Bump @babel/core from 7.25.8 to 7.25.9
2024-10-23 15:22:31 -04:00
Víctor Losada Hernández
41cbb67155 Merge branch 'master' into fix-snippetbar-behaviour 2024-10-23 21:21:45 +02:00
Trevor Buckner
1ab6ef078e Merge branch 'master' into dependabot/npm_and_yarn/babel/core-7.25.9 2024-10-23 15:21:40 -04:00
Trevor Buckner
25a7af5b70 Merge pull request #3847 from naturalcrit/dependabot/npm_and_yarn/babel/preset-react-7.25.9
Bump @babel/preset-react from 7.25.7 to 7.25.9
2024-10-23 15:21:27 -04:00
dependabot[bot]
5f41decdb6 Bump @babel/core from 7.25.8 to 7.25.9
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.25.8 to 7.25.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.9/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-23 19:04:33 +00:00
Trevor Buckner
3a1053ad70 Merge branch 'master' into dependabot/npm_and_yarn/babel/preset-react-7.25.9 2024-10-23 15:03:23 -04:00
Trevor Buckner
d768a41746 Merge pull request #3846 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.37.2
Bump eslint-plugin-react from 7.37.1 to 7.37.2
2024-10-23 15:03:14 -04:00
Trevor Buckner
f5f22fe0e9 Merge pull request #3805 from 5e-Cleric/add-notification-client-side
Add notification client side
2024-10-23 15:01:14 -04:00
G.Ambatte
27c5f86205 Merge branch 'master' into addAdminFixScriptTool-#3801 2024-10-24 07:32:52 +13:00
G.Ambatte
361d1c1aff Merge branch 'master' into refactorVersionHistory 2024-10-24 07:32:09 +13:00
Víctor Losada Hernández
88e5f26dd8 not render snippets element if empty 2024-10-23 20:16:30 +02:00
Víctor Losada Hernández
ddfccba822 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into add-notification-client-side 2024-10-23 19:48:45 +02:00
Víctor Losada Hernández
069d054e30 remove console logs and lint 2024-10-23 19:47:12 +02:00
Víctor Losada Hernández
1f7ff4386b fix html in notifs 2024-10-23 19:45:47 +02:00
Trevor Buckner
6373c398bc Fix scroll PR when no hash 2024-10-23 13:45:10 -04:00
Víctor Losada Hernández
7a78408415 Merge branch 'add-notification-client-side' of https://github.com/5e-Cleric/homebrewery; branch 'master' of https://github.com/naturalcrit/homebrewery into add-notification-client-side 2024-10-23 19:33:14 +02:00
Víctor Losada Hernández
52311f989d Merge branch 'userpage-to-func-comp' of https://github.com/5e-Cleric/homebrewery into userpage-to-func-comp 2024-10-23 17:03:02 +02:00
Víctor Losada Hernández
b9bf9c7e70 "Refactor UserPage component: removed unnecessary import, updated function signature, and moved useState hook declaration" 2024-10-23 17:03:00 +02:00
Víctor Losada Hernández
45ada35a11 Merge branch 'master' into userpage-to-func-comp 2024-10-23 12:48:17 +02:00
Víctor Losada Hernández
9d2a305f03 initial commit 2024-10-23 09:02:23 +02:00
dependabot[bot]
9cc7799d5c Bump @babel/preset-react from 7.25.7 to 7.25.9
Bumps [@babel/preset-react](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react) from 7.25.7 to 7.25.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.9/packages/babel-preset-react)

---
updated-dependencies:
- dependency-name: "@babel/preset-react"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-23 03:42:08 +00:00
dependabot[bot]
c235695f04 Bump eslint-plugin-react from 7.37.1 to 7.37.2
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.37.1 to 7.37.2.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.1...v7.37.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-23 03:41:54 +00:00
Víctor Losada Hernández
999a96b5ce "Rename dismissKeys to dismisskeys in Dialog component and its usage" 2024-10-22 21:46:57 +02:00
Trevor Buckner
ef5e3ddf4c Merge pull request #3506 from naturalcrit/scroll-to-element
Get external link and scroll to element
2024-10-22 14:10:11 -04:00
Trevor Buckner
d5f498cbf9 Merge branch 'master' into scroll-to-element 2024-10-22 14:09:49 -04:00
Trevor Buckner
5040b9528f cleanup 2024-10-22 14:08:20 -04:00
Trevor Buckner
83a48b8d0c Simplify observer 2024-10-22 13:58:35 -04:00
Trevor Buckner
9fbdd24d01 Cleanup 2024-10-22 13:52:34 -04:00
Trevor Buckner
5b136f651c Call scrollToHash from our existing "frameDidMount`
`frameDidMount` is equivalent to using iframe.addEventListener('load');

Let's not add a new listener and just use the existing event we already have. Functionality still works.
2024-10-22 13:03:12 -04:00
Trevor Buckner
effeef0d67 Merge pull request #3842 from naturalcrit/dependabot/npm_and_yarn/eslint-9.13.0
Bump eslint from 9.12.0 to 9.13.0
2024-10-21 13:28:22 -04:00
Trevor Buckner
cf3d5df582 Merge branch 'master' into dependabot/npm_and_yarn/eslint-9.13.0 2024-10-21 11:25:56 -04:00
Trevor Buckner
71cdbf1079 Merge pull request #3843 from naturalcrit/dependabot/npm_and_yarn/superagent-10.1.1
Bump superagent from 10.1.0 to 10.1.1
2024-10-21 11:25:41 -04:00
Trevor Buckner
712db7dfa7 Merge branch 'master' into dependabot/npm_and_yarn/superagent-10.1.1 2024-10-21 11:22:46 -04:00
Trevor Buckner
ed48c6664b Merge pull request #3844 from G-Ambatte/catchIDBErrors
Catch IndexedDB errors
2024-10-21 09:59:29 -04:00
G.Ambatte
917f20cdd5 Merge branch 'master' into catchIDBErrors 2024-10-21 16:27:30 +13:00
G.Ambatte
0c98f832bb Add catch to await calls 2024-10-21 16:21:41 +13:00
dependabot[bot]
41a60e6312 Bump superagent from 10.1.0 to 10.1.1
Bumps [superagent](https://github.com/ladjs/superagent) from 10.1.0 to 10.1.1.
- [Release notes](https://github.com/ladjs/superagent/releases)
- [Changelog](https://github.com/ladjs/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/ladjs/superagent/compare/v10.1.0...v10.1.1)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-21 03:20:23 +00:00
dependabot[bot]
5994e0d0b3 Bump eslint from 9.12.0 to 9.13.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.12.0 to 9.13.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.12.0...v9.13.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-21 03:20:07 +00:00
Trevor Buckner
c723f820f7 Merge pull request #3635 from naturalcrit/snippet-bar-wrapping
Snippet bar wrapping
2024-10-20 13:04:48 -04:00
Trevor Buckner
0e9021049c lint 2024-10-20 13:00:05 -04:00
Víctor Losada Hernández
1d663ef38d last iteration 2024-10-20 12:19:38 +02:00
Víctor Losada Hernández
d3e11ead54 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into snippet-bar-wrapping 2024-10-20 12:19:26 +02:00
Trevor Buckner
79e1f4caf7 Merge pull request #3838 from naturalcrit/Allow-Markdown/styles-to-update-on-any-text-change
Allow Markdown/Style to update on any text change
2024-10-19 00:11:44 -04:00
Trevor Buckner
59e397a65a Merge branch 'master' into Allow-Markdown/styles-to-update-on-any-text-change 2024-10-19 00:10:35 -04:00
Trevor Buckner
6b066c3fd3 Merge pull request #3837 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.7.2
Bump mongoose from 8.7.1 to 8.7.2
2024-10-18 14:59:10 -04:00
Trevor Buckner
b7413714be Merge branch 'master' into dependabot/npm_and_yarn/mongoose-8.7.2 2024-10-18 12:58:04 -04:00
Trevor Buckner
ec49d5e526 Merge pull request #3836 from dbolack-ab/MigrateGlobaltocToggles
Migrate .tocGlobalH? toggles
2024-10-18 10:56:33 -04:00
Trevor Buckner
d53a271c9f Change to .page and tweak spacing/newlines to match other snippets
All of our "global" style snippets are just set at `.page`, not `.pages`. This still applies globally but is consistent with our current approach.
2024-10-18 10:53:16 -04:00
Trevor Buckner
9d81f50b60 Remove disabled = false
Don't need that tag at all when it's false.
2024-10-18 10:46:59 -04:00
Trevor Buckner
ac766f3b37 Update brewRenderer.jsx 2024-10-18 10:23:56 -04:00
dependabot[bot]
cd09408aa8 Bump mongoose from 8.7.1 to 8.7.2
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.7.1 to 8.7.2.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.7.1...8.7.2)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-18 03:37:53 +00:00
David Bolack
631ef795b7 Fix .tocGlobalH?
Based on OH DEAR GOD THE LAG! discoveries related to the global toggles, these are being moved from a markup tag to a styles tab insert.
2024-10-17 18:30:31 -05:00
David Bolack
01c4e3ec1f Merge branch 'master' of github.com:naturalcrit/homebrewery 2024-10-17 18:14:45 -05:00
Víctor Losada Hernández
5a75182aff changes as requested, wrapping of editor tools, and linting 2024-10-18 00:52:26 +02:00
Víctor Losada Hernández
8538ccabe6 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into snippet-bar-wrapping 2024-10-17 23:47:02 +02:00
Víctor Losada Hernández
8ef88a4799 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-10-17 23:42:57 +02:00
Víctor Losada Hernández
189625c79b adding margin to scroll action to prevent toolbar overlapping 2024-10-17 23:38:27 +02:00
Víctor Losada Hernández
d872a496a7 fix mutation observer integration 2024-10-17 23:38:11 +02:00
Trevor Buckner
a1d2b5314b Merge pull request #3834 from naturalcrit/DisablePagesHasSelector
Disable Global ToC Snippet
2024-10-17 17:05:11 -04:00
Víctor Losada Hernández
9a4473526a move around 2 2024-10-17 22:59:29 +02:00
Víctor Losada Hernández
5077fda3f6 move stuff around for minimal changes 2024-10-17 22:58:14 +02:00
Víctor Losada Hernández
397ae31f56 remove stale changes 2024-10-17 22:56:58 +02:00
Trevor Buckner
f2f06b23fd Disable Global ToC Snippet 2024-10-17 16:42:57 -04:00
Víctor Losada Hernández
87915ef0ef remove unnecessary changes 2024-10-17 22:42:55 +02:00
Víctor Losada Hernández
c9240c7023 fix last line pack-lock 2024-10-17 22:41:24 +02:00
Víctor Losada Hernández
e54d237a19 fix pack-lock 2024-10-17 22:40:53 +02:00
Víctor Losada Hernández
ccfd5578cf Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-10-17 22:39:28 +02:00
Víctor Losada Hernández
618e865e52 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into add-notification-client-side 2024-10-17 22:29:31 +02:00
Trevor Buckner
4dd07a3c11 Merge pull request #3815 from G-Ambatte/tweakBrewRendererBackgroundStyle
Tweak color of Brew Renderer background text
2024-10-16 16:25:11 -04:00
Trevor Buckner
7888bfa878 Merge branch 'master' into tweakBrewRendererBackgroundStyle 2024-10-16 16:23:47 -04:00
Trevor Buckner
17b77f5460 Merge pull request #3832 from naturalcrit/memoizeRenderPages 2024-10-15 22:41:55 -04:00
Trevor Buckner
d348d1e689 Merge branch 'master' into memoizeRenderPages 2024-10-15 22:41:27 -04:00
Trevor Buckner
2aa60f793d Fix /new
/new starts with no `text` so it will crash without `?.`
2024-10-15 22:39:13 -04:00
Trevor Buckner
72739f28e8 Merge pull request #3831 from naturalcrit/memoizeRenderPages 2024-10-15 22:18:46 -04:00
Trevor Buckner
f1aeea18d4 Only jump when on text panel 2024-10-15 22:07:55 -04:00
Trevor Buckner
321bbba4b8 Rearrange 2024-10-15 22:07:41 -04:00
Trevor Buckner
36af1cdb7f Update brewRenderer.jsx 2024-10-15 21:47:27 -04:00
Trevor Buckner
0813daf01f Merge pull request #3826 from naturalcrit/dependabot/npm_and_yarn/react-router-dom-6.27.0
Bump react-router-dom from 6.26.2 to 6.27.0
2024-10-15 10:39:10 -04:00
dependabot[bot]
6d137d9ca8 Bump react-router-dom from 6.26.2 to 6.27.0
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.26.2 to 6.27.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/react-router-dom@6.27.0/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.27.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-15 14:38:35 +00:00
Trevor Buckner
5490cc9fe6 Merge pull request #3825 from naturalcrit/dependabot/npm_and_yarn/stylelint-16.10.0
Bump stylelint from 16.9.0 to 16.10.0
2024-10-15 10:37:15 -04:00
dependabot[bot]
10283e6e45 Bump stylelint from 16.9.0 to 16.10.0
Bumps [stylelint](https://github.com/stylelint/stylelint) from 16.9.0 to 16.10.0.
- [Release notes](https://github.com/stylelint/stylelint/releases)
- [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint/stylelint/compare/16.9.0...16.10.0)

---
updated-dependencies:
- dependency-name: stylelint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-14 03:49:21 +00:00
David Bolack
154ee06fc4 iMerge branch 'master' of github.com:naturalcrit/homebrewery 2024-10-13 21:27:11 -05:00
Gazook89
810c2140c9 move some toolbar specific styling to toolbar.less 2024-10-13 20:45:05 -05:00
Gazook89
c4fbc8d827 Merge branch 'master' into View-Modes 2024-10-13 09:40:05 -05:00
Gazook89
96ae07a456 Small style change on checkbox inputs 2024-10-13 09:39:41 -05:00
G.Ambatte
0d1291a713 Merge branch 'master' into addAdminFixScriptTool-#3801 2024-10-13 22:47:32 +13:00
Víctor Losada Hernández
3c66907a86 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-10-13 11:15:15 +02:00
Víctor Losada Hernández
0663e82fa1 remove unnecessary space in homepage markdown 2024-10-13 10:58:24 +02:00
Víctor Losada Hernández
6e241c5bcd remove splitpane parent 2024-10-13 10:53:05 +02:00
Víctor Losada Hernández
ebe5dca7a9 remove unnecessary child in nav 2024-10-13 10:51:06 +02:00
Gazook89
b33d9264d3 unify terms to 'spreads'
This commit only renames things, changes no logic.  Any mention of "book", "view", or "mode" is renamed in relation to "spreads".

The AnchoredBox.jsx file is renamed to Anchored.jsx

Extra icons are deleted, and the remaining ones are renamed.
2024-10-12 23:25:14 -05:00
Gazook89
0855c5c181 remove errant console.log 2024-10-12 23:12:37 -05:00
Gazook89
1741abc3fe Refactor AnchoredBox for greater flexibility
Big change to how the AnchoredBox component is structured so that it can be used in more than just one spot.  Now composed of the wrapper Anchored, with two children AnchoredTrigger and AnchoredBox, each of which can have their own arbitrary children.

Next steps will involve renaming the component file to Anchored.jsx, moving most styling out of the attached stylesheet (and into brewRenderer.less), and adding props to pass in Anchor Positioning properties.
2024-10-12 23:12:27 -05:00
Trevor Buckner
f1af87ee7e Merge pull request #3821 from naturalcrit/v3.16.0 2024-10-12 23:21:01 -04:00
Trevor Buckner
7dcceb983e Update changelog to v3.16.0 2024-10-12 23:10:13 -04:00
G.Ambatte
63f4104f81 Add UI to Admin page 2024-10-13 13:45:24 +13:00
G.Ambatte
6bc865144a Add cleaning function to API 2024-10-13 13:45:11 +13:00
G.Ambatte
ccafee7a21 Get text from textBin in brew object 2024-10-13 13:44:33 +13:00
G.Ambatte
033a089fd8 Merge branch 'master' into refactorVersionHistory 2024-10-13 12:17:27 +13:00
Gazook89
27f471791d Small change in title phrasing 2024-10-12 13:28:25 -05:00
Gazook89
ae11da2bc7 Fix the styles overriding previous styles
If there were two inputs sending styles to the same target (ie row and column gap), they would override each other.

This change fixes that by deepening the merges.  Admittedly, I turned to cGPT to help me with this as the nesting was throwing me for a loop.  It works, though, and I understand it now that I can read it.
2024-10-12 11:53:52 -05:00
Gazook89
b58b9ca8f0 Merge branch 'View-Modes-Radio-Options' into View-Modes 2024-10-12 11:06:09 -05:00
Gazook89
ba0b3e7d93 Add toggle for Page Shadows
Reworks the pagesStyles to a broader object previewStyles.  This new object has this structure:

```
{
  targetElement : { cssProperty: value }
}
```
2024-10-12 11:05:23 -05:00
Trevor Buckner
6d4b1843ae Fix missed lines from 3.15.2 branch 2024-10-12 00:10:43 -04:00
Gazook89
6fca21b6ed set defaultValue of gap sliders
defaultValue matches the normal styled values of the gap property on the .pages element.

removed the "tooltip" that showed the current value from the range sliders inside the anchoredbox (the gap sliders).
2024-10-11 22:53:38 -05:00
Trevor Buckner
76d6679002 Fix line endings on app.js 2024-10-11 23:50:08 -04:00
Trevor Buckner
4efa1b10f3 Merge pull request #3808 from naturalcrit/v3.15.2 2024-10-11 23:48:34 -04:00
Trevor Buckner
b9e15746c3 Update app.js 2024-10-11 23:47:45 -04:00
Trevor Buckner
1fff75cc5e Update homebrew.api.js 2024-10-11 23:42:20 -04:00
Trevor Buckner
9037cf1750 Update homebrew.api.js 2024-10-11 23:41:54 -04:00
Trevor Buckner
dfe26280d2 Update app.js 2024-10-11 23:38:00 -04:00
Trevor Buckner
7894d9fbec Update app.js 2024-10-11 23:35:15 -04:00
Gazook89
a3dbaf9e6a refactor anchoredBox to handle focus
Refactoring the AnchoredBox component because I wanted to set focus on the trigger button when the expanded box was closed.  Wrapping the trigger into it's own component, with forwardRef, allows for passing the `ref` to the actual DOM node.  Then the `.focus()` method will work on it.
2024-10-11 22:34:40 -05:00
Gazook89
835305bcf6 Add a title to each button
add a role to the toolbr.
2024-10-11 22:32:53 -05:00
Trevor Buckner
c3173d2e14 Update homebrew.api.js 2024-10-11 23:25:55 -04:00
Trevor Buckner
4859756ef8 Update homebrew.api.js 2024-10-11 23:23:56 -04:00
Trevor Buckner
1c47d743d6 Remove 429 error 2024-10-11 23:20:32 -04:00
Trevor Buckner
bfbbbe9e86 Update package.json 2024-10-11 23:19:44 -04:00
Trevor Buckner
1aaa146412 Update package-lock.json 2024-10-11 23:19:17 -04:00
Trevor Buckner
086d85c08b Remove Error 55 2024-10-11 23:18:03 -04:00
Trevor Buckner
134fe7d372 Remove /ip path 2024-10-11 23:15:56 -04:00
Trevor Buckner
836dfbade2 SetSaveDelayTo10s 2024-10-11 23:15:03 -04:00
Trevor Buckner
52a7ce9866 Merge branch 'master' into v3.15.2 2024-10-11 23:08:41 -04:00
Gazook89
395f2d16fa change view mode toggles to indiv buttons
Rather than a single button with three states, it is three buttons.  Went with buttons with `role='radio'` rather than true radios mostly because that is what Radix does.
2024-10-11 22:06:41 -05:00
Gazook89
6cabdc0a67 add alternative icons in
the `-alt` icons have better sizing/readability than the originals.  The originals likely will be removed.

Also adds back in 'fit-width' icon which was mistakenly overwritten earlier.
2024-10-11 22:05:18 -05:00
G.Ambatte
f64e7d3fd7 Shift grabage collection to use delMany instead of a looped del 2024-10-12 10:57:01 +13:00
G.Ambatte
cdbb2fa26a Add IDB custom store wrapper 2024-10-12 10:55:02 +13:00
G.Ambatte
bec830c3b8 Tweak color of Brew Renderer background text 2024-10-12 08:09:51 +13:00
Gazook89
e80588b234 Add icons 2024-10-11 13:51:41 -05:00
Gazook89
73504a3386 Setting a padding-top to avoid pages hugging toolbar 2024-10-11 13:51:06 -05:00
Gazook89
9c4b936ddd bump node to avoid experimental flag issues from another merge 2024-10-11 13:50:40 -05:00
David Bolack
222d49bdca Merge branch 'master' of github.com:naturalcrit/homebrewery 2024-10-11 12:08:57 -05:00
Trevor Buckner
05f3f40e47 Merge pull request #3812 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.25.8
Bump @babel/preset-env from 7.25.7 to 7.25.8
2024-10-11 12:11:57 -04:00
dependabot[bot]
7cad7fd319 Bump @babel/preset-env from 7.25.7 to 7.25.8
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.25.7 to 7.25.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.8/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-11 16:07:18 +00:00
Trevor Buckner
dca9099d00 Merge pull request #3811 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.25.8
Bump @babel/core from 7.25.7 to 7.25.8
2024-10-11 12:06:05 -04:00
David Bolack
f386be3494 Merge branch 'master' of github.com:naturalcrit/homebrewery 2024-10-11 09:07:15 -05:00
Gazook89
c4074d67f5 Merge branch 'master' into View-Modes 2024-10-10 23:34:26 -05:00
dependabot[bot]
fa78d04e89 Bump @babel/core from 7.25.7 to 7.25.8
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.25.7 to 7.25.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.8/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-11 03:50:24 +00:00
Trevor Buckner
5f9dfc9258 Merge pull request #3688 from G-Ambatte/experimentalDeploymentIdentification 2024-10-10 23:11:14 -04:00
G.Ambatte
d534eddb29 Remove unnecessary useEffect import 2024-10-11 13:14:53 +13:00
G.Ambatte
9099db5ea1 Remove obsolete state and event handlers 2024-10-11 11:56:29 +13:00
G.Ambatte
a9a8b4b9bb Shift static height style to LESS file 2024-10-11 11:55:51 +13:00
G.Ambatte
5d29d40c97 Implement suggested change 2024-10-11 11:42:03 +13:00
David Bolack
9506be6b65 Revert "Revert --experimental-vm-modules"
This reverts commit 1aabb84731.
2024-10-10 17:41:40 -05:00
David Bolack
1aabb84731 Revert --experimental-vm-modules
Code works but does not work with jest as expected.
2024-10-10 17:40:32 -05:00
G.Ambatte
4291284252 Merge branch 'master' into experimentalDeploymentIdentification 2024-10-11 11:10:28 +13:00
Víctor Losada Hernández
fcede5448e Merge pull request #3492 from 5e-Cleric/fix-vulnerability-admin-pages
Fix admin vulnerability to Brute Force
2024-10-10 23:05:06 +02:00
Víctor Losada Hernández
c47974cb49 suggested changes 2024-10-10 23:00:39 +02:00
Víctor Losada Hernández
4fde4600bc fix pack 2024-10-10 22:58:55 +02:00
Víctor Losada Hernández
27f939201d Merge branch 'master' of https://github.com/naturalcrit/homebrewery into fix-vulnerability-admin-pages 2024-10-10 22:54:22 +02:00
Víctor Losada Hernández
6e2cde507d revert package completely 2024-10-10 22:50:29 +02:00
Víctor Losada Hernández
95d6e39a44 Revert "remove changes package lock"
This reverts commit 00f1d4a27e.
2024-10-10 22:49:19 +02:00
Víctor Losada Hernández
39b8cbae2a Revert "remove package 2"
This reverts commit 0162232053.
2024-10-10 22:49:16 +02:00
Víctor Losada Hernández
0162232053 remove package 2 2024-10-10 22:44:51 +02:00
Víctor Losada Hernández
00f1d4a27e remove changes package lock 2024-10-10 22:43:13 +02:00
Víctor Losada Hernández
db618fe2ad linting changes 2024-10-10 22:42:47 +02:00
Víctor Losada Hernández
47f2703388 remove unrelated change 2024-10-10 22:38:50 +02:00
Víctor Losada Hernández
52e929ee68 remove spaces added 2024-10-10 22:36:59 +02:00
Víctor Losada Hernández
f74e72a35f remove rate-limit 2024-10-10 22:32:17 +02:00
Trevor Buckner
e3d256aaaf Merge pull request #3800 from G-Ambatte/addIndexedDM-#3763
Change local version history to use Indexed DB
2024-10-10 15:38:52 -04:00
G.Ambatte
f65dee28cb Merge branch 'master' into addIndexedDM-#3763 2024-10-11 07:44:05 +13:00
Trevor Buckner
58dd1b147d Merge pull request #3807 from naturalcrit/dependabot/npm_and_yarn/globals-15.11.0
Bump globals from 15.10.0 to 15.11.0
2024-10-10 13:45:14 -04:00
Trevor Buckner
f84dcd9fce Merge branch 'master' into dependabot/npm_and_yarn/globals-15.11.0 2024-10-10 11:52:18 -04:00
Trevor Buckner
cc1ab35255 Merge pull request #3806 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.7.1
Bump mongoose from 8.7.0 to 8.7.1
2024-10-10 11:52:09 -04:00
Víctor Losada Hernández
b2c3d620a4 Merge branch 'master' into add-notification-client-side 2024-10-10 13:30:36 +02:00
Víctor Losada Hernández
2d8874acaf move back to conditional showing instead of conditional rendering 2024-10-10 13:17:24 +02:00
Víctor Losada Hernández
001bf4a605 move dismisskeys into state for proper rerender 2024-10-10 12:56:37 +02:00
G.Ambatte
803ca09ab6 Merge branch 'master' into addIndexedDM-#3763 2024-10-10 21:55:00 +13:00
dependabot[bot]
8a60a4a5cc Bump globals from 15.10.0 to 15.11.0
Bumps [globals](https://github.com/sindresorhus/globals) from 15.10.0 to 15.11.0.
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v15.10.0...v15.11.0)

---
updated-dependencies:
- dependency-name: globals
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-10 03:23:29 +00:00
dependabot[bot]
a345b67ffe Bump mongoose from 8.7.0 to 8.7.1
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.7.0 to 8.7.1.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.7.0...8.7.1)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-10 03:23:22 +00:00
Trevor Buckner
456cefd535 Merge pull request #3786 from dbolack-ab/nanoid-fix 2024-10-09 22:24:03 -04:00
Víctor Losada Hernández
2b6e166e86 Revert "types react apparently needed?"
This reverts commit 55b5c1e713.
2024-10-10 02:09:52 +02:00
Víctor Losada Hernández
f8c995e59e remove comments 2024-10-10 02:09:11 +02:00
Víctor Losada Hernández
656c9399ef initial commit 2024-10-10 02:06:00 +02:00
Víctor Losada Hernández
55b5c1e713 types react apparently needed? 2024-10-10 01:16:50 +02:00
G.Ambatte
ab6861675d Comment out history testing values 2024-10-10 09:07:54 +13:00
G.Ambatte
0deb9073cd Remove obsolete file 2024-10-10 08:57:41 +13:00
G.Ambatte
d5cda45d4d Merge branch 'master' into addIndexedDM-#3763 2024-10-10 08:50:39 +13:00
G.Ambatte
36674f4cf2 Add explicit guard clause to renderHistoryItems 2024-10-10 08:48:14 +13:00
G.Ambatte
618de544bf Remove unnecessary check 2024-10-10 08:43:38 +13:00
G.Ambatte
8f5b421531 Fix infinite loop 2024-10-10 08:34:24 +13:00
G.Ambatte
8db12739d3 Remove obsolete function 2024-10-10 08:34:15 +13:00
Víctor Losada Hernández
6456c22c61 testing mutation Observer, don't review this yet 2024-10-09 21:33:26 +02:00
Trevor Buckner
4cb093c0c0 Merge branch 'master' into nanoid-fix 2024-10-09 15:10:03 -04:00
Trevor Buckner
9f0f9a9169 Merge pull request #2586 from G-Ambatte/experimentalNotificationDB 2024-10-09 15:09:25 -04:00
Trevor Buckner
a9aab5bb0c Add test for error handling deleting notifications 2024-10-09 14:52:56 -04:00
Trevor Buckner
5ca970bdee Typo 2024-10-09 14:46:18 -04:00
Trevor Buckner
9635e1a8eb Change another return to throw 2024-10-09 14:41:37 -04:00
Trevor Buckner
23e3c98a0d Add test for adding notification without dismissKey 2024-10-09 14:40:38 -04:00
Trevor Buckner
346bb0086e Should throw, not return errors, so they land in catch 2024-10-09 14:40:11 -04:00
Trevor Buckner
e873dcf3a8 Fix error messages crashing page 2024-10-09 14:35:16 -04:00
Trevor Buckner
269dd6107c Merge branch 'master' into experimentalNotificationDB 2024-10-09 11:12:23 -04:00
Trevor Buckner
8281db8543 Merge pull request #3804 from naturalcrit/dependabot/npm_and_yarn/cookie-parser-1.4.7 2024-10-09 11:07:27 -04:00
dependabot[bot]
66db3ecdc1 Bump cookie-parser from 1.4.6 to 1.4.7
Bumps [cookie-parser](https://github.com/expressjs/cookie-parser) from 1.4.6 to 1.4.7.
- [Release notes](https://github.com/expressjs/cookie-parser/releases)
- [Changelog](https://github.com/expressjs/cookie-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/cookie-parser/compare/1.4.6...1.4.7)

---
updated-dependencies:
- dependency-name: cookie-parser
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-09 15:06:37 +00:00
Trevor Buckner
1ef61b32d4 Merge pull request #3803 from naturalcrit/dependabot/npm_and_yarn/express-4.21.1 2024-10-09 11:05:13 -04:00
G.Ambatte
dc66d36b2d Simplify history loading 2024-10-09 19:35:48 +13:00
G.Ambatte
0bd3b53dd1 Merge branch 'master' into addIndexedDM-#3763 2024-10-09 19:00:45 +13:00
G.Ambatte
5651c66562 Fix race condition 2024-10-09 18:29:15 +13:00
G.Ambatte
fb2d03f5a2 Change to test values 2024-10-09 17:50:26 +13:00
G.Ambatte
0b44e68a36 Simplify garbage collection 2024-10-09 17:27:33 +13:00
dependabot[bot]
fe7ee78cae Bump express from 4.21.0 to 4.21.1
Bumps [express](https://github.com/expressjs/express) from 4.21.0 to 4.21.1.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.0...4.21.1)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-09 03:25:09 +00:00
G.Ambatte
aa68762294 Simplify historyCheck logic 2024-10-09 15:59:11 +13:00
G.Ambatte
2a9402634f Remove unnecessary guard clause 2024-10-09 14:58:20 +13:00
G.Ambatte
291e16b124 Revert to use local consts instead of config vars 2024-10-09 14:57:04 +13:00
G.Ambatte
e75eb72d3f Remove obsolete function 2024-10-09 14:54:23 +13:00
Trevor Buckner
7bf95dd0ca Merge pull request #3132 from dbolacksn/Issue_1958 2024-10-08 17:13:19 -04:00
Trevor Buckner
80a21e3f27 Merge branch 'master' into Issue_1958 2024-10-08 17:12:05 -04:00
Trevor Buckner
a921d0a9bb Merge pull request #3802 from Gazook89/Remove-Unused-Nav-Components 2024-10-08 17:10:20 -04:00
Trevor Buckner
9acecb63ed Merge branch 'master' into addIndexedDM-#3763 2024-10-08 17:07:39 -04:00
Gazook89
a6efaf0e8b Remove unused Nav components 2024-10-08 10:12:53 -05:00
David Bolack
c4b754e467 Lost a stray ) on update 2024-10-07 14:45:33 -05:00
David Bolack
e82411d3d2 Merge branch 'master' into Issue_1958 2024-10-07 14:35:19 -05:00
David Bolack
5080fd068a Merge branch 'master' into nanoid-fix 2024-10-07 14:32:19 -05:00
Trevor Buckner
88d36bcf85 Merge pull request #3798 from naturalcrit/dependabot/npm_and_yarn/eslint-9.12.0
Bump eslint from 9.11.1 to 9.12.0
2024-10-07 13:24:31 -04:00
dependabot[bot]
e2243efe82 Bump eslint from 9.11.1 to 9.12.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.11.1 to 9.12.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.11.1...v9.12.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 15:10:37 +00:00
Trevor Buckner
337531a622 Merge pull request #3797 from naturalcrit/dependabot/npm_and_yarn/stylistic/stylelint-plugin-3.1.1
Bump @stylistic/stylelint-plugin from 3.1.0 to 3.1.1
2024-10-07 11:09:18 -04:00
Víctor Losada Hernández
e396a51ad5 Merge branch 'v3.15.2' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-10-07 11:47:13 +02:00
G.Ambatte
7e165c6e61 Remove unnecessary key check 2024-10-07 21:53:24 +13:00
G.Ambatte
5d9ef3fa6c Add custom IDB store 2024-10-07 21:53:05 +13:00
G.Ambatte
24bffacaeb GC functional, config values now actually used 2024-10-07 20:53:32 +13:00
G.Ambatte
1e38ed8d1f Bump max-lines 2024-10-07 20:53:05 +13:00
G.Ambatte
25ce1aa00c Functional history menu 2024-10-07 19:36:17 +13:00
G.Ambatte
97f8493319 Merge branch 'master' into addIndexedDM-#3763 2024-10-07 18:32:05 +13:00
G.Ambatte
c9241e3091 WIP Update 2024-10-07 18:22:06 +13:00
dependabot[bot]
70118022b8 Bump @stylistic/stylelint-plugin from 3.1.0 to 3.1.1
Bumps [@stylistic/stylelint-plugin](https://github.com/stylelint-stylistic/stylelint-stylistic) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/stylelint-stylistic/stylelint-stylistic/releases)
- [Changelog](https://github.com/stylelint-stylistic/stylelint-stylistic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint-stylistic/stylelint-stylistic/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: "@stylistic/stylelint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 03:36:16 +00:00
Gazook89
68c75fbfd2 adjust CSS to support Firefox
Set's a non-ideal but functional css style for the box when using Firefox so the box is at least visible.
2024-10-06 22:16:46 -05:00
Gazook89
d6d6cc1e29 Add View Mode Options
Adds a new AnchoredBox component that is functionally a clone of the "saving error" notifications, but drops a lot of the JS in favor of the new (chrome-only!) CSS Anchor Positioning API.  In subsequent commits, either alternate styling or a polyfill will be added non-supported browsers.

The box contains a few inputs that modify the CSS applied to `.pages`, most critically a "start on right" toggle for the Facing Pages mode.
2024-10-06 21:51:44 -05:00
Gazook89
9fce94af63 Small CSS tweaks/display 'value' tooltip only if exists
The range slider should only display a tooltip for the value if the value attribute exists.  For example, the difference between controlled and uncontrolled inputs.

Update toolBar.less
2024-10-06 21:26:48 -05:00
Gazook89
41f390b305 Add a classname to recto configuration
Adding class name so that it can be toggled between 'recto' and 'verso'.  Verso being the normal left/right configuration, no styling is needed.  With recto, the first page is shifted to the second slot, or right side.
2024-10-06 21:24:50 -05:00
Trevor Buckner
226e714f32 Merge pull request #3793 from 5e-Cleric/fix-wrong-brew-id-links-generated 2024-10-06 15:57:11 -04:00
Trevor Buckner
f3332fb95b Merge branch 'master' into fix-wrong-brew-id-links-generated 2024-10-06 15:54:37 -04:00
Trevor Buckner
10d4cd4ab3 Merge pull request #3796 from naturalcrit/FixGoogleLinksinUserPage 2024-10-06 15:52:29 -04:00
Trevor Buckner
2a523c4955 Fix links to google drive files in user page
User page was not marking Google Brews as "stubbed" if the brew belongs   to another users' Google Drive or your own credentials are expired (it searches the current user drive for google files and checks if those are stubbed)

This now sets *every* file found on Mongo as "Stubbed", whether the Drive file belongs to the current user or not.
2024-10-06 15:48:10 -04:00
Víctor Losada Hernández
64dd71601c last changes 2024-10-06 19:59:58 +02:00
Víctor Losada Hernández
4968300e7a return correct data 2024-10-06 19:54:41 +02:00
Víctor Losada Hernández
3acb25ce3a adress comments 2024-10-06 19:43:51 +02:00
Víctor Losada Hernández
487a574f50 initital fix 2024-10-06 00:05:12 -04:00
Gazook89
8115b1504e Add flex property to pages 2024-10-05 23:01:08 -05:00
Gazook89
34fa724fdd Change .pages margin to .brewRenderer padding
More consistent visuals since the zooming of the .pages element affects the spacing around the edges, and the brewRenderer padding isn't affected.
2024-10-05 22:43:13 -05:00
Gazook89
24544e713e Basically revert previous change
Adding the margin resets back in because otherwise each .page margin is set to "auto" on the sides, and that makes them zoom awkwardly when in facing and flow modes.
2024-10-05 22:35:42 -05:00
Gazook89
06a806e260 preserve margin around .pages
Keep margin around .pages element such that the pages are never bumped right against the divider.
2024-10-05 21:55:42 -05:00
Gazook89
4259931b67 Merge branch 'master' into View-Modes 2024-10-05 21:39:06 -05:00
Víctor Losada Hernández
a4e0f1fc0f initital fix 2024-10-04 22:18:11 +02:00
Trevor Buckner
2ada6ce70d Merge pull request #3789 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.25.7
Bump @babel/core from 7.25.2 to 7.25.7
2024-10-04 13:53:11 -04:00
dependabot[bot]
132878fd8c Bump @babel/core from 7.25.2 to 7.25.7
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.25.2 to 7.25.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.7/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-04 17:49:46 +00:00
Trevor Buckner
0146ab7ce0 Merge pull request #3787 from naturalcrit/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.25.7
Bump @babel/plugin-transform-runtime from 7.25.4 to 7.25.7
2024-10-04 13:48:31 -04:00
dependabot[bot]
a29addbfa3 Bump @babel/plugin-transform-runtime from 7.25.4 to 7.25.7
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.25.4 to 7.25.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.7/packages/babel-plugin-transform-runtime)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-04 17:46:56 +00:00
Trevor Buckner
796f8ac8b7 Merge pull request #3788 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.25.7
Bump @babel/preset-env from 7.25.4 to 7.25.7
2024-10-04 13:45:42 -04:00
dependabot[bot]
19d76bd077 Bump @babel/preset-env from 7.25.4 to 7.25.7
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.25.4 to 7.25.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.7/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-04 14:51:12 +00:00
Trevor Buckner
f59a250bb1 Merge pull request #3790 from naturalcrit/dependabot/npm_and_yarn/babel/preset-react-7.25.7
Bump @babel/preset-react from 7.24.7 to 7.25.7
2024-10-04 10:49:52 -04:00
David Bolack
5b64052c21 Helps if I update the tests. 2024-10-03 18:49:16 -05:00
David Bolack
f00e76319c Hard code latest as min 2024-10-03 18:44:47 -05:00
David Bolack
a844b29165 Try further down the updates. 2024-10-03 18:40:22 -05:00
David Bolack
fcd1a2de5b Update node version one release. 2024-10-03 09:16:08 -05:00
Víctor Losada Hernández
5eb1456915 fix tests 2 2024-10-03 09:15:08 +02:00
Víctor Losada Hernández
a82e9758b3 fix test errors 2024-10-03 09:08:24 +02:00
Víctor Losada Hernández
6adac74f76 updated test 2024-10-03 09:01:12 +02:00
Víctor Losada Hernández
3c3b4d8466 "Updated mock implementation for deleting a notification in admin API test" 2024-10-03 09:00:57 +02:00
Víctor Losada Hernández
9cc4d2d7c5 add last test 2024-10-03 08:53:27 +02:00
Víctor Losada Hernández
d216216df7 remove unnecessary methods and comments 2024-10-03 08:48:54 +02:00
dependabot[bot]
9fd92e00a1 Bump @babel/preset-react from 7.24.7 to 7.25.7
Bumps [@babel/preset-react](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-react) from 7.24.7 to 7.25.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.7/packages/babel-preset-react)

---
updated-dependencies:
- dependency-name: "@babel/preset-react"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-03 03:17:35 +00:00
David Bolack
afeadb5417 Enable --experimental-require-module flag on node build in order to support ESM module only modules. 2024-10-02 22:05:09 -05:00
Trevor Buckner
e9286d4bb7 Merge pull request #3784 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.37.1
Bump eslint-plugin-react from 7.37.0 to 7.37.1
2024-10-01 23:39:13 -04:00
dependabot[bot]
22dbe1ebf0 Bump eslint-plugin-react from 7.37.0 to 7.37.1
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.37.0 to 7.37.1.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.37.0...v7.37.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-02 03:34:52 +00:00
Trevor Buckner
53761bc567 Merge pull request #3785 from naturalcrit/dependabot/npm_and_yarn/globals-15.10.0
Bump globals from 15.9.0 to 15.10.0
2024-10-01 23:33:33 -04:00
dependabot[bot]
e6e9029bb7 Bump globals from 15.9.0 to 15.10.0
Bumps [globals](https://github.com/sindresorhus/globals) from 15.9.0 to 15.10.0.
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v15.9.0...v15.10.0)

---
updated-dependencies:
- dependency-name: globals
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-02 03:26:23 +00:00
Trevor Buckner
1a325fb3c5 New notification 2024-10-01 22:25:17 -04:00
Trevor Buckner
84f49aebce Add test for "add notification" 2024-10-01 21:54:22 -04:00
Trevor Buckner
8949248bc4 Example test
Added an example test that queries /admin/notification/all and checks if the response returns a list of notifications.

Since we don't have a real database, we overwrite (mock) NotificationModel to just return some fake data, otherwise the test would crash.
2024-10-01 17:15:36 -04:00
Víctor Losada Hernández
df06d8fcd3 update error index 2024-10-01 21:58:52 +02:00
Víctor Losada Hernández
d6ca6592a2 remove rateLimiter 2024-10-01 21:58:42 +02:00
Trevor Buckner
0110c6afed Remove duplicate error log for googleActions.list 2024-10-01 15:06:11 -04:00
Trevor Buckner
0e29620710 Remove delayMiddleware and ratelimiter 2024-10-01 14:13:15 -04:00
Trevor Buckner
c33b44855a Go back to service account for brew updates 2024-10-01 12:17:30 -04:00
G.Ambatte
77f162f7a4 Initial IDB functionality pass 2024-10-01 23:53:35 +13:00
Trevor Buckner
bc475b5ed9 Merge pull request #3762 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.37.0
Bump eslint-plugin-react from 7.36.1 to 7.37.0
2024-09-30 14:14:21 -04:00
Trevor Buckner
0415af624a Merge branch 'master' into dependabot/npm_and_yarn/eslint-plugin-react-7.37.0 2024-09-30 13:52:13 -04:00
Trevor Buckner
8a63859546 Merge pull request #3778 from 5e-Cleric/fix-lang-on-share
fix lang on share page
2024-09-30 13:51:50 -04:00
Trevor Buckner
8d5bc9e37c Merge pull request #3767 from G-Ambatte/fixToolbarZoomInPrint-#3744
Add zoom property to BrewRenderer print styling
2024-09-30 13:51:37 -04:00
Trevor Buckner
313f18c74c Merge branch 'master' into fixToolbarZoomInPrint-#3744 2024-09-30 13:50:00 -04:00
Trevor Buckner
0c6bc5d7ac Merge pull request #3757 from naturalcrit/v3.15.1
Fix Rate Limiting
2024-09-30 13:48:53 -04:00
Trevor Buckner
db6c689914 Merge branch 'master' into fix-lang-on-share 2024-09-30 13:48:20 -04:00
Víctor Losada Hernández
d4970ed119 initial commit 2024-09-30 17:48:07 +02:00
Trevor Buckner
e7e35294c6 disable rate limiter 2024-09-30 10:59:43 -04:00
Trevor Buckner
e9c45b216c Add retryconfig and forward user ip 2024-09-30 08:31:39 -04:00
Trevor Buckner
40925253bd autosave to 16 seconds 2024-09-30 00:59:30 -04:00
Trevor Buckner
66433d9e77 5 requests 2024-09-30 00:45:10 -04:00
Trevor Buckner
3a6750613b express proxy settings 2024-09-30 00:31:58 -04:00
dependabot[bot]
e45fddad60 Bump eslint-plugin-react from 7.36.1 to 7.37.0
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.36.1 to 7.37.0.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.36.1...v7.37.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 04:24:03 +00:00
Trevor Buckner
a31f1da4dc Merge branch 'master' into v3.15.1 2024-09-30 00:23:04 -04:00
Trevor Buckner
3ec3cf8df8 Merge pull request #3741 from naturalcrit/dependabot/npm_and_yarn/stylistic/stylelint-plugin-3.1.0 2024-09-30 00:22:49 -04:00
Trevor Buckner
a7361f8450 add delay between get and update 2024-09-30 00:14:37 -04:00
Trevor Buckner
32fa272947 reduce rate limit to 60 requests in 5 minutes 2024-09-30 00:03:27 -04:00
Trevor Buckner
68895bdca2 Rate limit /api requests from each IP address
100 requests each 5 minutes.
2024-09-29 23:37:26 -04:00
dependabot[bot]
4d6d8a5e5a Bump @stylistic/stylelint-plugin from 3.0.1 to 3.1.0
Bumps [@stylistic/stylelint-plugin](https://github.com/stylelint-stylistic/stylelint-stylistic) from 3.0.1 to 3.1.0.
- [Release notes](https://github.com/stylelint-stylistic/stylelint-stylistic/releases)
- [Changelog](https://github.com/stylelint-stylistic/stylelint-stylistic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint-stylistic/stylelint-stylistic/compare/v3.0.1...v3.1.0)

---
updated-dependencies:
- dependency-name: "@stylistic/stylelint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-30 01:54:47 +00:00
Trevor Buckner
96acd334a0 Merge pull request #3742 from naturalcrit/dependabot/npm_and_yarn/eslint-9.11.1 2024-09-29 21:53:36 -04:00
Trevor Buckner
8ab6a8599d Use personal auth if logged in via google. 2024-09-29 21:47:45 -04:00
dependabot[bot]
a0aa975d07 Bump eslint from 9.11.0 to 9.11.1
Bumps [eslint](https://github.com/eslint/eslint) from 9.11.0 to 9.11.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.11.0...v9.11.1)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-29 18:24:55 +00:00
Trevor Buckner
8a06257a50 Merge pull request #3766 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.7.0 2024-09-29 14:23:41 -04:00
Trevor Buckner
ea656e5119 Issue notice 2024-09-29 00:15:26 -04:00
Trevor Buckner
aaa0acdfea Merge branch 'master' into v3.15.1 2024-09-28 23:40:25 -04:00
G.Ambatte
570c850c4f Merge branch 'master' into fixToolbarZoomInPrint-#3744 2024-09-28 09:05:22 +12:00
G.Ambatte
17dfacd5c9 Add zoom property to BrewRenderer print styling 2024-09-28 09:03:00 +12:00
dependabot[bot]
6d904111f7 Bump mongoose from 8.6.3 to 8.7.0
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.6.3 to 8.7.0.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.6.3...8.7.0)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-27 19:16:48 +00:00
Trevor Buckner
f1f686d8c7 Merge pull request #3760 from naturalcrit/dependabot/npm_and_yarn/dompurify-3.1.7 2024-09-27 15:15:43 -04:00
Trevor Buckner
6e120c2d05 Merge pull request #3765 from G-Ambatte/fixLegacyBrewRenders-#3764 2024-09-27 15:15:26 -04:00
Trevor Buckner
9b58db9f1e Let sharepage update page numbers 2024-09-27 15:03:29 -04:00
Trevor Buckner
ae123a8310 Change the other page number values as well 2024-09-27 11:35:01 -04:00
G.Ambatte
1f047890ab Change default value of currentEditorCursorPageNum 2024-09-27 23:32:19 +12:00
Trevor Buckner
58b0e12fcc Update app.js 2024-09-27 00:34:35 -04:00
Trevor Buckner
51f4c83ec0 Update app.js 2024-09-27 00:34:12 -04:00
Trevor Buckner
9decaf73f7 Update app.js 2024-09-27 00:19:08 -04:00
Trevor Buckner
15fde76209 Merge branch 'master' into v3.15.1 2024-09-27 00:13:32 -04:00
Trevor Buckner
2ba160fe65 Re-remove extra error log for new google brews. 2024-09-27 00:08:23 -04:00
dependabot[bot]
606af87e0f Bump dompurify from 3.1.6 to 3.1.7
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.1.6 to 3.1.7.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.1.6...3.1.7)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-27 03:53:15 +00:00
Trevor Buckner
05ad8e17a7 Merge pull request #3755 from naturalcrit/RaiseAutoSaveDelay 2024-09-26 19:17:51 -04:00
Trevor Buckner
bf87225415 Merge branch 'v3.15.1' into RaiseAutoSaveDelay 2024-09-26 19:17:35 -04:00
Trevor Buckner
8b61e69b77 Merge pull request #3754 from naturalcrit/RemoveDoubleGoogleDriveLogs 2024-09-26 19:15:46 -04:00
Trevor Buckner
e260eb0911 Raise timeout to 10 s.
No need to be stingy here... Can lower back down if this works.
2024-09-26 19:14:16 -04:00
Trevor Buckner
c8424e0b10 Remove test that no longer applies 2024-09-26 19:12:19 -04:00
Trevor Buckner
ff9a75f6b6 Remove duplicate error logs for google drive update / new
Errors are now logged once in the central error handler in app.js
2024-09-26 19:00:07 -04:00
Víctor Losada Hernández
ab32695ac9 test admin stuff 2024-09-25 11:34:56 +02:00
Gazook89
a96ff6ecb3 Variable name changes for clarity
Followed suggestions on the PR.
2024-09-23 21:05:37 -05:00
Gazook89
5af45f16b0 remove tagInput-class
This file was just the old StringArrayEditor that I kept around for easy reference.  Can be deleted now.
2024-09-23 14:54:24 -05:00
Gazook89
a9b6d5ff38 Merge branch 'master' into Functional-Tag-Editor 2024-09-23 14:53:41 -05:00
Trevor Buckner
cd0bf9c947 Merge pull request #3740 from naturalcrit/dependabot/npm_and_yarn/stylelint-config-recess-order-5.1.1
Bump stylelint-config-recess-order from 5.1.0 to 5.1.1
2024-09-23 15:20:43 -04:00
dependabot[bot]
c039a90624 Bump stylelint-config-recess-order from 5.1.0 to 5.1.1
Bumps [stylelint-config-recess-order](https://github.com/stormwarning/stylelint-config-recess-order) from 5.1.0 to 5.1.1.
- [Release notes](https://github.com/stormwarning/stylelint-config-recess-order/releases)
- [Changelog](https://github.com/stormwarning/stylelint-config-recess-order/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stormwarning/stylelint-config-recess-order/compare/v5.1.0...v5.1.1)

---
updated-dependencies:
- dependency-name: stylelint-config-recess-order
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 15:17:32 +00:00
Trevor Buckner
0e8387ec0d Merge pull request #3734 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.6.3
Bump mongoose from 8.6.2 to 8.6.3
2024-09-23 11:16:08 -04:00
dependabot[bot]
1347374ff7 Bump mongoose from 8.6.2 to 8.6.3
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.6.2 to 8.6.3.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.6.2...8.6.3)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 13:54:45 +00:00
Trevor Buckner
9419186e78 Merge pull request #3739 from naturalcrit/dependabot/npm_and_yarn/eslint-9.11.0
Bump eslint from 9.10.0 to 9.11.0
2024-09-23 09:53:30 -04:00
dependabot[bot]
58c6e6a446 Bump eslint from 9.10.0 to 9.11.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.10.0 to 9.11.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.10.0...v9.11.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 03:35:10 +00:00
Trevor Buckner
6e2bc1cabe Merge pull request #3723 from naturalcrit/sort-in-vault
Add sorting options to Vault Page
2024-09-20 16:03:17 -04:00
Trevor Buckner
971be6375e lint 2024-09-20 16:02:09 -04:00
Trevor Buckner
4353c01032 Update server/vault.api.js 2024-09-20 16:01:29 -04:00
Víctor Losada Hernández
d09cecedd7 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into sort-in-vault 2024-09-20 20:54:14 +02:00
Víctor Losada Hernández
235e3f484f last changes, linted 2024-09-20 20:52:30 +02:00
Víctor Losada Hernández
b53b279241 fix pagination not applying sort 2024-09-20 20:38:54 +02:00
Víctor Losada Hernández
4fd358771a fix class by suggestion 2024-09-20 20:25:33 +02:00
Víctor Losada Hernández
02147411e3 fix sort and dir props 2024-09-20 20:23:58 +02:00
Víctor Losada Hernández
5d68cddd18 update state when necessary 2024-09-20 15:43:19 +02:00
Víctor Losada Hernández
74a065e747 minor css fix 2024-09-20 15:31:19 +02:00
Gazook89
433f016c25 rename tag container class to unify with fields 2024-09-19 15:57:40 -05:00
Gazook89
10a9bc2906 Merge branch 'master' into Functional-Tag-Editor 2024-09-19 15:54:08 -05:00
Trevor Buckner
87c6343f30 Merge pull request #3736 from Gazook89/metadataEditor-tweaks 2024-09-19 16:51:37 -04:00
Gazook89
b585e85f0f Fix multiple duplicate tags updating at once
Fixes an issue where tags with duplicate values would all update to the same value after editing just one.

Also an adjustment to the parameters that are passed to handleInputKeyDown-- they are now one object.  This helps handle an "options" object where more optional features can be turned on and off.
2024-09-19 15:48:47 -05:00
Gazook89
544f4c6103 tweak headers 2024-09-19 15:29:35 -05:00
Gazook89
8a67e1eccd Merge branch 'Functional-Tag-Editor' into Func-Tag-Editor-Features 2024-09-19 14:54:28 -05:00
Gazook89
a6ac6b98c2 some fixes and updates
This fixes something i broke with last commit, but should be final commit.
2024-09-19 11:09:22 -05:00
Gazook89
2336f8508b Rearrange CSS and small HTML changes
Simplified and unified some font-size declarations, adjusted the "descriptions" for various inputs to be similar structure and appearance, change the components h1 label from "Brew" to "Properties Editor", updated the comment about Publishing.
2024-09-19 10:57:55 -05:00
Gazook89
7ea1696065 Adjust html structure to handle tags as list
Begin work on setting a better html structure for the component.

Create a .less file for the component, which I may not actually use.
2024-09-19 10:40:09 -05:00
Gazook89
5b4a7c168f Add comma to "submit" buttons
Now comma (`,`) submits a tag, like `Enter`
2024-09-18 23:54:12 -05:00
Gazook89
a54adc1e4b Set new tag input to clear itself after submission
Now whenever a new tag is submitted, the input element is cleared and ready for the next tag.

Whitespace cleanup.
2024-09-18 23:39:26 -05:00
Gazook89
c1288ce4bb Use index to find and remove tags
Fixes issue in last commit, so removing a tag that has duplicate value of other tags only removes the correct one, not the others as well.
2024-09-18 23:24:10 -05:00
Gazook89
c65210b3ed Add 'remove' button and method
New button that triggers `submitTag()` method directly (rather than throw onKeyDown event) and passes `null` as the newValue.  New `if` condition checks for null on newValue and if true, removes the tag that matches the originalValue.

This *does* currently delete all duplicate tags if they match the one you are deleting.  Not sure when you'd ever want duplicate tags, but regardless i'll likely switch this to work via Index, not value.
2024-09-18 23:13:46 -05:00
Gazook89
70a3cb9ef9 Add method for adding new tags
Component now accepts new tags entered in the always-present input field.  Entering a value and hitting Enter submits the tag, and it appears as a new tag.

Updated the tag list keys to be unique (via `index`).

To-Do: empty 'new tag' input after submitting.
2024-09-18 22:46:00 -05:00
Gazook89
d1686c4c8f Add in handlers for TagInput value changes
Now brew metadata is actually updated and preserved across reloads to match updated tag values.  useEffect calls the props.onChange event from the parent component on every change to the valueContext state of this component (right now, after hitting Enter in a tag input).
2024-09-18 22:18:18 -05:00
Gazook89
c5033db336 add editing of input functionality
Currently uses uncontrolled inputs with a `defaultValue` attribute set to the values passed in via props.  The input can then be edited, and when `Enter` is pressed, it updates the stored value state.  Later, this can be updated to be trigger with `Tab` or clicking outside the active input element.
2024-09-18 21:00:24 -05:00
David Bolack
672b787cd5 Merge branch 'Issue_1958' of github.com:dbolacksn/homebrewery-broken into Issue_1958 2024-09-18 16:28:19 -05:00
David Bolack
931566636b Merge branch 'master' into Issue_1958 2024-09-18 16:26:39 -05:00
David Bolack
ffaca4ec10 Update server/middleware/content-negotiation.js
Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
2024-09-18 16:21:31 -05:00
Trevor Buckner
fabc0bea83 Merge branch 'experimentalNotificationDB' of https://github.com/G-Ambatte/homebrewery into pr/2586 2024-09-18 15:50:55 -04:00
Trevor Buckner
5c2ad7dfee More Linting 2024-09-18 15:50:46 -04:00
Víctor Losada Hernández
3e7d4714a2 Merge branch 'experimentalNotificationDB' of https://github.com/G-Ambatte/homebrewery into experimentalNotificationDB 2024-09-18 21:47:05 +02:00
Víctor Losada Hernández
77c4ac6640 deleting useless state 2024-09-18 21:47:03 +02:00
Trevor Buckner
a7c892c1bb Lint 2024-09-18 15:36:48 -04:00
Trevor Buckner
dca7086522 Merge branch 'experimentalNotificationDB' of https://github.com/G-Ambatte/homebrewery into pr/2586 2024-09-18 15:35:12 -04:00
Trevor Buckner
6c42a7e180 Lint 2024-09-18 15:34:58 -04:00
Víctor Losada Hernández
e8c2858154 Merge branch 'experimentalNotificationDB' of https://github.com/G-Ambatte/homebrewery into experimentalNotificationDB 2024-09-18 21:32:19 +02:00
Víctor Losada Hernández
84f84782f5 Merge branch 'experimentalNotificationDB' of https://github.com/G-Ambatte/homebrewery; branch 'master' of https://github.com/naturalcrit/homebrewery into experimentalNotificationDB 2024-09-18 21:32:17 +02:00
Trevor Buckner
3caec793d8 Linting 2024-09-18 15:30:30 -04:00
Trevor Buckner
9717f0cd66 Split state into separate states. 2024-09-18 15:09:53 -04:00
Trevor Buckner
0cdc1947c1 Linting 2024-09-18 14:45:17 -04:00
Gazook89
36aa4ea508 Add click handler for readTags to open text input
Clicking on a readTag now converts that tag to a text input, and maintains the tag value.  It also closes any other open text inputs amongst the tags (but leaves the "new tag" input open).
2024-09-17 23:50:59 -05:00
Gazook89
d5c5b4315b Render tags as "write" or "read"
Tags are now either "readTag" or "writeTag", with the former being a div with the tag value and the latter a text input with the value.

Minor class name change in LESS.
2024-09-17 23:28:56 -05:00
Gazook89
d505e4e24c Render element for each value from props
Take an array of values from props, load it into valueContext state with an "editing" boolean for each value.  Then, when rendering the component, take each value in the valueContext array and create a div for each --

at this point, if the value is "being edited", it returns a div with text "editing".  If not being edited, it returns a div with the value as text.

Nothing is being edited at this point since that functionality doesn't exist yet.
2024-09-17 23:16:06 -05:00
Gazook89
ea7f18e3b0 Merge branch 'master' into Functional-Tag-Editor 2024-09-17 14:50:31 -05:00
Gazook89
e8e16f4d66 Initial commit: Rename component, set basic structure
No actual functionality implemented yet, just renames the component from "StringArrayEditor" to "TagInput", for brevity at the possible cost of clarity.  For now, the original StringArrayEditor is kept and named "TagInput-class.jsx" so that I can reference it as I work on the functional component.
2024-09-17 14:46:56 -05:00
Trevor Buckner
a8e5a96c98 Merge pull request #3733 from naturalcrit/fix-history-state-snippetbar-error
fix
2024-09-17 15:33:57 -04:00
Víctor Losada Hernández
f024bea493 delete unused error 2024-09-17 19:58:49 +02:00
Víctor Losada Hernández
61d77b4d2d fix 2024-09-17 19:55:50 +02:00
Víctor Losada Hernández
2e5ebb861e simplify logic 2024-09-17 19:50:39 +02:00
Víctor Losada Hernández
1b577c4030 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-09-17 13:20:32 +02:00
Víctor Losada Hernández
bbe4b5f978 Merge branch 'master' into fix-vulnerability-admin-pages 2024-09-17 12:47:18 +02:00
Víctor Losada Hernández
14d2534542 linting 2024-09-17 12:46:24 +02:00
Víctor Losada Hernández
3b49b5180e update error to auth 2024-09-17 12:25:54 +02:00
Víctor Losada Hernández
30e042635c Merge pull request #3724 from dbolack-ab/Pagella
Add Pagella Font family to Blank
2024-09-17 08:11:13 +02:00
David Bolack
3c04d491e6 Merge branch 'master' into Pagella 2024-09-16 18:34:07 -05:00
David Bolack
41e08831c6 Update font format. 2024-09-16 18:30:59 -05:00
Trevor Buckner
32c583ece8 Merge pull request #3634 from naturalcrit/nav-wrapping 2024-09-16 19:29:51 -04:00
Víctor Losada Hernández
a92b44427d lint 2024-09-16 23:17:12 +02:00
Víctor Losada Hernández
5961e9042a merge from master 2024-09-16 23:11:27 +02:00
Víctor Losada Hernández
2028f3dccd removing console log 2024-09-16 23:04:30 +02:00
Víctor Losada Hernández
8e4fc01831 linting 2024-09-16 23:03:50 +02:00
Víctor Losada Hernández
e92c169e71 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-09-16 23:01:40 +02:00
Víctor Losada Hernández
e2ae6898fd Merge branch 'master' of https://github.com/naturalcrit/homebrewery into fix-vulnerability-admin-pages 2024-09-16 23:00:52 +02:00
Trevor Buckner
471de9df9f Merge pull request #3692 from 5e-Cleric/more-style-snippets
Style snippets, more page sizes, A3, A5, Card
2024-09-16 16:55:58 -04:00
Trevor Buckner
398e6ef6f2 Slight rearranging 2024-09-16 16:53:55 -04:00
Víctor Losada Hernández
44262e2aae change initial status code 2024-09-16 22:52:56 +02:00
Víctor Losada Hernández
d8e174e143 update package-lock, apparently 2024-09-16 22:41:59 +02:00
Víctor Losada Hernández
bb59f0bbae moving page sizes around 2024-09-16 22:38:58 +02:00
Víctor Losada Hernández
c50ffe0723 linting 2024-09-16 22:38:08 +02:00
Víctor Losada Hernández
0d2878a7e7 merge from master and change error codes 2024-09-16 22:34:28 +02:00
Víctor Losada Hernández
a0d043439c Merge branch 'master' of https://github.com/naturalcrit/homebrewery into fix-vulnerability-admin-pages 2024-09-16 22:29:16 +02:00
Víctor Losada Hernández
8126271ea3 Merge branch 'fix-vulnerability-admin-pages' of https://github.com/5e-Cleric/homebrewery into fix-vulnerability-admin-pages 2024-09-16 22:25:17 +02:00
Víctor Losada Hernández
9bb21ddd04 Merge branch 'more-style-snippets' of https://github.com/5e-Cleric/homebrewery into more-style-snippets 2024-09-16 22:20:54 +02:00
Víctor Losada Hernández
746cd34087 suggested changes 2024-09-16 22:20:51 +02:00
Víctor Losada Hernández
313727035b suggested changes 2024-09-16 22:18:13 +02:00
Trevor Buckner
1a8611c528 Merge branch 'master' into more-style-snippets 2024-09-16 16:07:47 -04:00
Trevor Buckner
f7aa9346e9 Merge pull request #3711 from G-Ambatte/experimentalLocalStorageHistory
Store limited Brew History in Local Storage
2024-09-16 16:05:28 -04:00
G.Ambatte
83a7636b6f Simplify historyExists state logic 2024-09-17 07:41:34 +12:00
G.Ambatte
53c05a3ef6 Remove unused default item 2024-09-17 07:27:52 +12:00
Trevor Buckner
e20e681888 Merge branch 'master' into experimentalLocalStorageHistory 2024-09-16 11:10:45 -04:00
Trevor Buckner
f8fef1187c Merge pull request #3689 from dbolack-ab/GlobalToCToggles
Add Style Tab Snippets for Globally toggling additional header inclusion
2024-09-16 11:06:21 -04:00
Trevor Buckner
a866b45c55 Merge branch 'master' into GlobalToCToggles 2024-09-16 09:45:35 -04:00
G.Ambatte
8ceb422156 Separate bundled setState calls 2024-09-16 19:40:11 +12:00
G.Ambatte
8315df33ae Change empty slot logic 2024-09-16 19:39:51 +12:00
G.Ambatte
59f6f40ace Add seconds to display options 2024-09-16 19:24:39 +12:00
G.Ambatte
91f9a76af2 Remove spaces from code indentation 2024-09-16 19:20:14 +12:00
G.Ambatte
ae7404eb1f Remove comments 2024-09-16 19:15:16 +12:00
G.Ambatte
7a2fecf502 Set archiveBrew object directly
Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
2024-09-16 19:07:42 +12:00
Trevor Buckner
dfd3b99232 Merge branch 'master' into experimentalLocalStorageHistory 2024-09-16 01:50:54 -04:00
Trevor Buckner
a953bf0555 Merge pull request #3731 from naturalcrit/dependabot/npm_and_yarn/express-static-gzip-2.1.8 2024-09-16 01:44:48 -04:00
Trevor Buckner
88ff10d229 Merge pull request #3732 from naturalcrit/Linting 2024-09-16 01:44:34 -04:00
Trevor Buckner
8d479b8cd1 Lint whitespace changes 2024-09-16 01:42:44 -04:00
Trevor Buckner
63675a46e0 Lint more things 2024-09-16 01:42:21 -04:00
Trevor Buckner
5cc5eec619 Lint toolbar and snippetbar 2024-09-16 01:41:46 -04:00
Trevor Buckner
b5490e3a53 Lint editor.jsx 2024-09-16 01:40:21 -04:00
Trevor Buckner
1645a5acf4 Lint App.js
Just whitespace changes
2024-09-16 01:39:44 -04:00
Trevor Buckner
98c5b798a7 Merge branch 'master' into experimentalLocalStorageHistory 2024-09-16 01:03:29 -04:00
Trevor Buckner
295d878c3d Merge branch 'master' into dependabot/npm_and_yarn/express-static-gzip-2.1.8 2024-09-16 01:02:24 -04:00
Trevor Buckner
a283438b28 Merge pull request #3484 from dbolack-ab/Issue_241_Part_II 2024-09-16 00:51:04 -04:00
Trevor Buckner
48bdc417fa More logic simplification 2024-09-16 00:39:04 -04:00
dependabot[bot]
d2117259eb Bump express-static-gzip from 2.1.7 to 2.1.8
Bumps [express-static-gzip](https://github.com/tkoenig89/express-static-gzip) from 2.1.7 to 2.1.8.
- [Release notes](https://github.com/tkoenig89/express-static-gzip/releases)
- [Commits](https://github.com/tkoenig89/express-static-gzip/compare/v2.1.7...v2.1.8)

---
updated-dependencies:
- dependency-name: express-static-gzip
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-16 03:50:51 +00:00
David Bolack
67e265b23f Set default values for hb_images and hb_fonts in the config.
Remove stray tab.
2024-09-15 21:55:18 -05:00
Trevor Buckner
25a40e31c5 Remove console logs 2024-09-15 22:31:29 -04:00
Trevor Buckner
a353425d07 More cleanup 2024-09-15 22:13:41 -04:00
Trevor Buckner
c07c02f1d9 Remove unused variable 2024-09-15 21:44:02 -04:00
Trevor Buckner
81ab9417d3 Clean up unused code 2024-09-15 21:42:55 -04:00
Trevor Buckner
85401ba71b Fix BrewRenderer scrolling to 0 2024-09-15 21:26:49 -04:00
David Bolack
3ad0755c36 Correct ToC Global toggles subsnippets
The snippets incorrectedly reflected their previous incarnation as part of the Styles tab menus.
2024-09-15 18:33:14 -05:00
David Bolack
dc67c75130 Merge branch 'master' into Issue_1958 2024-09-15 18:15:19 -05:00
David Bolack
3388fccad7 Merge branch 'master' into Issue_241_Part_II 2024-09-15 18:11:38 -05:00
David Bolack
98cc79df92 Merge branch 'master' into Pagella 2024-09-15 18:03:51 -05:00
David Bolack
189363ec76 Merge branch 'master' into GlobalToCToggles 2024-09-15 18:03:16 -05:00
David Bolack
dbe56abb24 Merge branch 'master' of github.com:naturalcrit/homebrewery 2024-09-15 17:50:14 -05:00
Víctor Losada Hernández
e213eb0a78 "Refactor BrewRenderer: removed iframe load event listener, simplified page scrolling logic, and inlined getPageContainingElement functionality" 2024-09-15 18:37:27 +02:00
Víctor Losada Hernández
422829cbd8 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-09-15 16:52:12 +02:00
Trevor Buckner
84c0242eee Put page jump checks in componentDidUpdate
Jump when the current page for brew or editor changes
2024-09-15 00:13:49 -04:00
G.Ambatte
eddc81d051 Merge branch 'master' into experimentalLocalStorageHistory 2024-09-15 14:23:14 +12:00
G.Ambatte
2f392a7517 Lint fixes 2024-09-15 14:19:32 +12:00
G.Ambatte
531e6efa5e Get configuration from config files 2024-09-15 14:19:24 +12:00
G.Ambatte
72257dc71b Lint fixes 2024-09-15 14:09:56 +12:00
G.Ambatte
b456bb955a Initial UI functionality 2024-09-15 14:09:47 +12:00
Trevor Buckner
181c6bf65a Update editor.jsx 2024-09-14 19:15:39 -04:00
Trevor Buckner
d4fa5d55d0 Merge branch 'master' into pr/3484 2024-09-14 19:15:12 -04:00
Trevor Buckner
5a932b781b Merge pull request #3729 from naturalcrit/LiftRendererPageStateUp 2024-09-14 19:06:02 -04:00
Trevor Buckner
eebf24e1ba Merge branch 'LiftRendererPageStateUp' of https://github.com/naturalcrit/homebrewery into LiftRendererPageStateUp 2024-09-14 19:03:06 -04:00
Trevor Buckner
26a126859d Lint 2024-09-14 19:02:55 -04:00
Trevor Buckner
41b9a570b5 Merge branch 'master' into LiftRendererPageStateUp 2024-09-14 19:01:10 -04:00
Trevor Buckner
76c9f2ee71 Lint 2024-09-14 18:58:23 -04:00
Trevor Buckner
5c2acf3183 Let Editor pass changes up and inherit values down 2024-09-14 18:52:13 -04:00
Trevor Buckner
fa2874b18f Let brewRenderer pass changes up, and inherit values down 2024-09-14 18:50:38 -04:00
Trevor Buckner
7e776df4d4 Add Current Page states up into editor components, pass down to children 2024-09-14 18:50:09 -04:00
Víctor Losada Hernández
ebc3b4ee66 "Updated admin notification management: added error handling and styling, modified notification add and lookup functionality, and refactored server-side API routes and error handling." 2024-09-14 23:58:47 +02:00
G.Ambatte
7009ef4441 Remove unneeded brew.shareId reference 2024-09-15 00:47:54 +12:00
G.Ambatte
ff19e3875e Shift GC to use savedAt time 2024-09-14 23:43:44 +12:00
G.Ambatte
7ec2558eef Add guard clause for history UI items 2024-09-14 23:43:26 +12:00
G.Ambatte
a7cf49557a Tweak dropdown padding 2024-09-14 23:04:18 +12:00
G.Ambatte
c4c5ffff9b Tweak UI styling 2024-09-14 22:49:53 +12:00
G.Ambatte
719cc0c485 Remove onClick from UI 2024-09-14 22:49:39 +12:00
G.Ambatte
d01548feb6 Add getHistoryItems function 2024-09-14 21:20:31 +12:00
G.Ambatte
48eb42862a Add History styling 2024-09-14 17:32:20 +12:00
G.Ambatte
ace790739f Stub out History function on Editor Nav Bar 2024-09-14 17:32:07 +12:00
G.Ambatte
c77d6e5fae Simplify logic 2024-09-14 16:50:36 +12:00
G.Ambatte
b6bbed0e1b Merge branch 'master' into experimentalLocalStorageHistory 2024-09-14 13:59:14 +12:00
Víctor Losada Hernández
9bf28f1433 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimentalNotificationDB 2024-09-13 23:54:01 +02:00
Víctor Losada Hernández
dbbfb0b628 suggestions added, linted 2024-09-13 23:29:36 +02:00
Víctor Losada Hernández
4f2c2916d6 remove cx 2024-09-13 23:03:40 +02:00
Víctor Losada Hernández
629b51a26c remove logs and unecessary state 2024-09-13 20:33:58 +02:00
Víctor Losada Hernández
d947ff45e2 correct style to be coherent and nice 2024-09-13 20:33:21 +02:00
Víctor Losada Hernández
a2d260c297 remove lookup by id funct and fix lost state functions 2024-09-13 20:29:35 +02:00
Víctor Losada Hernández
c411691fd6 remove lookup by id and admin access middleware from lookup all 2024-09-13 20:29:09 +02:00
Trevor Buckner
4a9fe1dbdb Merge pull request #3727 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.36.1
Bump eslint-plugin-react from 7.35.2 to 7.36.1
2024-09-13 11:50:16 -04:00
dependabot[bot]
0ce0ae771b Bump eslint-plugin-react from 7.35.2 to 7.36.1
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.35.2 to 7.36.1.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.35.2...v7.36.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-13 15:45:11 +00:00
Trevor Buckner
6334d191f8 Merge pull request #3726 from naturalcrit/dependabot/npm_and_yarn/express-4.21.0
Bump express from 4.20.0 to 4.21.0
2024-09-13 11:43:57 -04:00
dependabot[bot]
75699874d0 Bump express from 4.20.0 to 4.21.0
Bumps [express](https://github.com/expressjs/express) from 4.20.0 to 4.21.0.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.20.0...4.21.0)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-13 15:26:06 +00:00
Trevor Buckner
f1633cf03c Merge pull request #3725 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.6.2
Bump mongoose from 8.6.1 to 8.6.2
2024-09-13 11:24:45 -04:00
Trevor Buckner
3ef91cb1ea Add check for scroll event complete/ lift page state up 2024-09-12 12:55:11 -04:00
Víctor Losada Hernández
f40c5e17ca change to 401 2024-09-12 14:04:35 +02:00
dependabot[bot]
5b8928685f Bump mongoose from 8.6.1 to 8.6.2
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.6.1 to 8.6.2.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.6.1...8.6.2)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-12 03:14:50 +00:00
David Bolack
1b0fd6bb33 Add Pagella face to Blank Template.
Pagella is a TeX update of the URW Palladio L face that is a good substitute for the commonly used Book Antiqua and Palatino faces.

    https://en.wikipedia.org/wiki/Palatino#:~:text=The%20first%20legal%20free%20version,on%20URW%20Palladio%20L%20font.
2024-09-10 20:52:19 -05:00
David Bolack
84d237e792 Revert "Add Pagella face to Blank Template."
This reverts commit 7d298565f9.
2024-09-10 20:50:47 -05:00
David Bolack
7d298565f9 Add Pagella face to Blank Template.
Pagella is a TeX update of the URW Palladio L face that is a good substitute for the commonly used Book Antiqua and Palatino faces.

https://en.wikipedia.org/wiki/Palatino#:~:text=The%20first%20legal%20free%20version,on%20URW%20Palladio%20L%20font.
2024-09-10 20:44:42 -05:00
David Bolack
7c59f56fb2 Explode tocInclude and tocExclude snippet menus to match tocGlobal and tocDepth pattern. 2024-09-10 20:22:50 -05:00
G.Ambatte
091e7e0b65 Merge branch 'master' into experimentalLocalStorageHistory 2024-09-11 07:38:42 +12:00
David Bolack
bc6b4e3bfc Move ToC Includes Menu from styles to Table of Contents subsnippet
Create additional subsnippets for .tocInclude*, .tocExclude*, and move the existing depth entries to a subsnippet.
2024-09-10 14:18:36 -05:00
David Bolack
5a2e071879 Merge branch 'master' into GlobalToCToggles 2024-09-10 14:12:04 -05:00
David Bolack
8fa5eeb0ef Merge branch 'master' into Issue_241_Part_II 2024-09-10 14:10:20 -05:00
David Bolack
59f27197f6 A few small cleanups for ToC
Explicitly define --TOC as included in :root so there is no doubt the default value.
Rearrange Block ToC inclusion classes for organization and comments

Add block level, single Header class exclusion convienance classes.
2024-09-10 13:34:47 -05:00
Trevor Buckner
1646ba7e25 Merge pull request #3481 from naturalcrit/metadata-api-endpoint
Add API endpoint to get metadata from brews
2024-09-10 13:36:17 -04:00
Trevor Buckner
29460edca9 Merge branch 'master' into metadata-api-endpoint 2024-09-10 13:26:40 -04:00
David Bolack
f8d170be87 Document level toggles need to look at pages, not page. 2024-09-10 12:15:12 -05:00
Trevor Buckner
2ecdd962bd Merge pull request #3721 from naturalcrit/dependabot/npm_and_yarn/react-router-dom-6.26.2
Bump react-router-dom from 6.26.1 to 6.26.2
2024-09-10 13:13:11 -04:00
David Bolack
ed376f3154 Oy, what a typo. 2024-09-10 11:25:06 -05:00
David Bolack
930974f66d Merge branch 'GlobalToCToggles' of github.com:dbolack-ab/homebrewery into GlobalToCToggles 2024-09-10 11:11:12 -05:00
dependabot[bot]
aba8946274 Bump react-router-dom from 6.26.1 to 6.26.2
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.26.1 to 6.26.2.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.26.2/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-10 16:01:10 +00:00
Trevor Buckner
a2b5903bde Merge pull request #3720 from naturalcrit/dependabot/npm_and_yarn/express-4.20.0
Bump express from 4.19.2 to 4.20.0
2024-09-10 11:59:55 -04:00
G.Ambatte
a93133a9f3 Merge branch 'master' into experimentalLocalStorageHistory 2024-09-10 23:13:13 +12:00
Víctor Losada Hernández
ea1d0714b4 initial commit 2024-09-10 08:28:34 +02:00
Víctor Losada Hernández
9f4cf60cda Merge branch 'master' into more-style-snippets 2024-09-10 08:05:36 +02:00
Trevor Buckner
e5ab223571 Better line position (viewport has some margin) 2024-09-10 01:25:26 -04:00
Trevor Buckner
45a9501459 Jump based on scroll position, not cursor position 2024-09-10 01:11:28 -04:00
Trevor Buckner
ec74b994d7 Simplify scroll event for source editor using lodash Throttle 2024-09-10 00:43:44 -04:00
Trevor Buckner
b5155ed256 remove unused variable 2024-09-09 23:40:06 -04:00
Trevor Buckner
315296458a Remove setting button styles in componentDidMount
Just set the state, and the renderer will know what to display.
2024-09-09 23:39:29 -04:00
dependabot[bot]
e601e19381 Bump express from 4.19.2 to 4.20.0
Bumps [express](https://github.com/expressjs/express) from 4.19.2 to 4.20.0.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.19.2...4.20.0)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-10 03:36:23 +00:00
Trevor Buckner
0fbb4879a9 Set button appearance based on state
Avoid manually editing the DOM elements. Let the Render function update the appearance based on state.
2024-09-09 23:35:18 -04:00
Trevor Buckner
51c8973a85 Move onClick from the lock icon to the whole button 2024-09-09 23:29:10 -04:00
Trevor Buckner
707b90e445 Merge branch 'master' into pr/3484 2024-09-09 23:22:00 -04:00
Trevor Buckner
7f656bc408 Merge pull request #3719 from naturalcrit/Refactor-tableOfContents.gen.js 2024-09-09 23:20:59 -04:00
Trevor Buckner
5c906ee722 Logic rewrite
Realized we don't need to build a whole descendency tree of all the headers. We can just track the current indendation level and what headers are at each indent. This removes about 1/4 of the code, and lets us put all of the exit conditions (no title, no showPage, ToCExclude) in one place to easily see what is being excluded and what not.
2024-09-09 23:16:56 -04:00
David Bolack
3629292ebb Remove 2024-09-09 17:09:24 -05:00
Trevor Buckner
2cb3ca6880 Merge pull request #3714 from Gazook89/Meta-Tags-for-Vault
Meta Tags for the Vault Page
2024-09-09 11:13:42 -04:00
Trevor Buckner
90ee9afb54 Merge pull request #3679 from dbolack-ab/skipCountingSnippet
Add Page number alteration snippets
2024-09-09 11:12:16 -04:00
Trevor Buckner
2284f15876 Update tableOfContents.gen.js 2024-09-09 11:11:40 -04:00
Trevor Buckner
bfcb904ab7 Merge branch 'master' into skipCountingSnippet 2024-09-09 11:10:47 -04:00
Trevor Buckner
232d3c66a4 Merge pull request #3705 from Gazook89/Hide-Toolbar-2
Add button to toggle Preview tools
2024-09-09 11:03:53 -04:00
Trevor Buckner
2b458d1265 Merge branch 'master' into Hide-Toolbar-2 2024-09-09 11:01:39 -04:00
Trevor Buckner
58a2993fe1 use className for react classes
Avoid warning of conflict with JS "class" keyword.
2024-09-09 11:00:45 -04:00
Trevor Buckner
0f8fcb9889 Merge pull request #3716 from 5e-Cleric/fix-arrows-in-vault-this-time-for-real
fixing it once and for all
2024-09-09 10:52:52 -04:00
Trevor Buckner
cbe3c79b6b Merge branch 'master' into fix-arrows-in-vault-this-time-for-real 2024-09-09 10:46:46 -04:00
Trevor Buckner
c707db4aa5 Merge pull request #3717 from naturalcrit/dependabot/npm_and_yarn/eslint-9.10.0
Bump eslint from 9.9.1 to 9.10.0
2024-09-09 10:46:33 -04:00
Trevor Buckner
87415d54d5 Merge branch 'master' into fix-arrows-in-vault-this-time-for-real 2024-09-09 10:46:24 -04:00
Trevor Buckner
7525509887 Merge branch 'master' into dependabot/npm_and_yarn/eslint-9.10.0 2024-09-09 10:40:11 -04:00
Trevor Buckner
e5a189939b Merge pull request #3639 from dbolack-ab/actualPageNumber
Rework page counters for skipping and resets.
2024-09-09 10:39:25 -04:00
dependabot[bot]
f3bc8f91cc Bump eslint from 9.9.1 to 9.10.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.9.1 to 9.10.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.9.1...v9.10.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 03:41:08 +00:00
David Bolack
3b4dd7dd61 Merge branch 'actualPageNumber' of github.com:dbolack-ab/homebrewery into actualPageNumber 2024-09-08 15:27:43 -05:00
David Bolack
4bc957159d Move a couple of variables back out of the global space because that was bad. 2024-09-08 15:23:03 -05:00
Trevor Buckner
7881d4b4a2 Small logic cleanup and renaming 2024-09-08 16:22:58 -04:00
David Bolack
1e9c7423c7 Fix "clicked on the toggle ring" crash with scroll lock.
The code was doing dom-climbing math based on clicking on the div contents but was attached to the div. Moved the onClick to the contents.
2024-09-07 22:36:27 -05:00
David Bolack
fa74fb4ada Update tooltips for locking. 2024-09-07 21:38:07 -05:00
David Bolack
7a37bf47c5 Bodge Render side mirroring back into place. 2024-09-07 21:33:51 -05:00
David Bolack
be70b9e67d Regroup page numbering snippets, update icons 2024-09-07 20:50:18 -05:00
David Bolack
f7a5097dd8 Merge branch 'master' into skipCountingSnippet 2024-09-07 20:43:28 -05:00
David Bolack
758c2799a1 That was the wrong way. Lets try this ugly fix. 2024-09-07 20:40:29 -05:00
David Bolack
b0dffc6df1 Drop empty entries 2024-09-07 20:35:43 -05:00
David Bolack
6ea724bb16 Start skipping .skipCount in ToC 2024-09-07 20:30:16 -05:00
David Bolack
b58688bd62 Stop comparing lengths, dude. 2024-09-07 20:19:56 -05:00
David Bolack
0f8461ced6 Not a collection. 2024-09-07 20:16:16 -05:00
David Bolack
3b0028da69 Move some of thos variables back. 2024-09-07 20:12:05 -05:00
David Bolack
049b64cd41 Remove unneeded variable 2024-09-07 19:54:52 -05:00
David Bolack
8709772f51 Merge branch 'actualPageNumber' of github.com:dbolack-ab/homebrewery into actualPageNumber 2024-09-07 19:54:13 -05:00
David Bolack
dcc7a22272 First pass at code fixes.
Move functions out of function
Use querySelector instead of querySelectorAll
Flip skip and reset counter order.
2024-09-07 19:47:16 -05:00
David Bolack
92f963d798 Merge branch 'master' into actualPageNumber 2024-09-07 18:59:12 -05:00
Víctor Losada Hernández
e5f6d28abd fixing it once and for all 2024-09-07 22:37:22 +02:00
Víctor Losada Hernández
3360b4e829 refctor logic 2024-09-07 19:12:59 +02:00
Víctor Losada Hernández
9e1a532105 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into scroll-to-element 2024-09-07 18:45:03 +02:00
Trevor Buckner
b124e55b3d Merge branch 'master' into Issue_241_Part_II 2024-09-06 23:51:14 -04:00
G.Ambatte
6e1cf63ed9 Merge branch 'experimentalLocalStorageHistory' of https://github.com/G-Ambatte/homebrewery into experimentalLocalStorageHistory 2024-09-07 14:07:36 +12:00
G.Ambatte
bc35b5245b Fix renamed variable 2024-09-07 14:07:30 +12:00
G.Ambatte
4033307473 Merge branch 'master' into experimentalLocalStorageHistory 2024-09-07 14:05:16 +12:00
G.Ambatte
cd30679aac Remove debugging line 2024-09-07 14:01:25 +12:00
G.Ambatte
9679e5b130 Add garbage collection function to remove version data after specified period without update 2024-09-07 14:00:31 +12:00
G.Ambatte
4d295f5f18 Add comments to elucidate the madness 2024-09-07 13:22:44 +12:00
G.Ambatte
6ed6b6d66f Remove debugging line 2024-09-07 13:10:36 +12:00
G.Ambatte
87ba4ee264 Basic functionality working 2024-09-07 13:07:58 +12:00
Trevor Buckner
5e9fad9b09 Merge branch 'master' into actualPageNumber 2024-09-06 16:56:49 -04:00
G.Ambatte
6693eebe64 Updated version saving logic 2024-09-07 08:47:53 +12:00
Trevor Buckner
f0a8bf379a Fix non-uniform spacing/indenting 2024-09-06 16:43:44 -04:00
Trevor Buckner
fb843ef3c1 Merge branch 'master' into GlobalToCToggles 2024-09-06 16:36:02 -04:00
Trevor Buckner
22678b15af Fix snippet filter 2024-09-06 16:35:18 -04:00
Trevor Buckner
d2cefa8bf7 Merge branch 'master' into GlobalToCToggles 2024-09-06 16:22:52 -04:00
Trevor Buckner
e5d0051075 Create pull_request_template.md 2024-09-06 15:57:33 -04:00
Trevor Buckner
df8fd077ca Merge pull request #3696 from dbolack-ab/snippets-no-gen 2024-09-06 14:16:50 -04:00
David Bolack
88caa81baa Merge branch 'master' into snippets-no-gen 2024-09-06 12:25:22 -05:00
David Bolack
4a1e4c1b80 Merge branch 'master' into actualPageNumber 2024-09-06 12:24:40 -05:00
David Bolack
cf4747553c Merge branch 'master' into skipCountingSnippet 2024-09-06 12:23:46 -05:00
David Bolack
a2497052b4 Merge branch 'master' into Issue_1958 2024-09-06 11:56:04 -05:00
David Bolack
240dfa3954 Merge branch 'Issue_1958' of github.com:dbolacksn/homebrewery-broken into Issue_1958
Only except /staticImages with a `local` NODE_ENV
2024-09-06 11:55:21 -05:00
David Bolack
d19aaf6c78 Except staticImages and staticFonts paths from middleware evaluation if in a local ENV. 2024-09-06 11:50:46 -05:00
David Bolack
e777fb542a Merge branch 'master' into GlobalToCToggles 2024-09-06 09:47:59 -05:00
David Bolack
5c9c342b10 Update client/homebrew/editor/snippetbar/snippetbar.jsx
Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
2024-09-06 01:25:13 -05:00
G.Ambatte
f3011eeef9 Update delay amounts 2024-09-06 16:58:30 +12:00
G.Ambatte
9fd581149b Shift version history to separate file 2024-09-06 16:57:11 +12:00
Trevor Buckner
84736980c9 Merge pull request #3713 from Gazook89/Fix-Vault-Styling-Issues
Fix Vault Page CSS specificity issues
2024-09-05 14:59:09 -04:00
Gazook89
03c14e5847 adds meta tags for the Vault page
So they show up when sharing the link in Discord or wherever.
2024-09-05 11:24:59 -05:00
Gazook89
e0be7a5db3 Move rules out of body and into more specific elements 2024-09-05 11:13:08 -05:00
Trevor Buckner
2e332d7699 Merge pull request #3710 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-jest-28.8.3
Bump eslint-plugin-jest from 28.8.2 to 28.8.3
2024-09-05 11:01:57 -04:00
G.Ambatte
03bc9a8189 Test of combined version and time differential requirement for update 2024-09-05 23:24:14 +12:00
G.Ambatte
421c88cc07 Save brew text/style to local storage 2024-09-05 22:35:14 +12:00
G.Ambatte
235969a485 Fix a dropped bracket 2024-09-05 16:50:19 +12:00
G.Ambatte
2e459118aa Update content-negotiation.js 2024-09-05 16:45:07 +12:00
G.Ambatte
ff60ca163f Merge branch 'master' into Issue_1958 2024-09-05 16:38:14 +12:00
dependabot[bot]
53979f2266 Bump eslint-plugin-jest from 28.8.2 to 28.8.3
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 28.8.2 to 28.8.3.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.8.2...v28.8.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-05 03:38:40 +00:00
David Bolack
4dc5746c71 Merge branch 'master' into Issue_1958 2024-09-04 20:52:46 -05:00
Trevor Buckner
780c92cb9b Merge pull request #3704 from G-Ambatte/experimentalGitAttribs 2024-09-04 19:38:41 -04:00
Trevor Buckner
20c54ef79e Merge branch 'master' into experimentalGitAttribs 2024-09-04 19:38:32 -04:00
Trevor Buckner
5ce69041fc Merge pull request #3708 from naturalcrit/fix-arrows
FIx missing arrows
2024-09-04 18:07:38 -04:00
Víctor Losada Hernández
20db8c6720 restore missing state 2024-09-04 23:57:44 +02:00
Trevor Buckner
ed35eb2680 Merge pull request #3702 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.6.1 2024-09-04 17:22:22 -04:00
Trevor Buckner
2a7b7cd50c Merge branch 'master' into dependabot/npm_and_yarn/mongoose-8.6.1 2024-09-04 17:21:44 -04:00
Trevor Buckner
d37fa03ec7 Merge pull request #3701 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.35.2 2024-09-04 17:21:33 -04:00
Trevor Buckner
2c7d39147d Merge branch 'master' into dependabot/npm_and_yarn/eslint-plugin-react-7.35.2 2024-09-04 17:20:58 -04:00
Trevor Buckner
6535e94ccd Merge pull request #3707 from naturalcrit/v3.15.0 2024-09-04 17:20:49 -04:00
Trevor Buckner
2ede3d7cf3 Merge branch 'master' into v3.15.0 2024-09-04 17:20:41 -04:00
Trevor Buckner
e56b2a7ce5 Merge pull request #3706 from 5e-Cleric/experimental-development 2024-09-04 17:20:21 -04:00
Trevor Buckner
ad8e004fa9 Update Dismisskey for popup
Need a new key so this new message will appear again for users who cleared the popup before
2024-09-04 17:16:11 -04:00
Trevor Buckner
e05d2e805c v3.15.0 2024-09-04 17:01:27 -04:00
Víctor Losada Hernández
a083999943 Merge branch 'master' into experimental-development 2024-09-04 22:54:09 +02:00
Víctor Losada Hernández
247bc719b8 fix z-index issue 2024-09-04 22:52:57 +02:00
Víctor Losada Hernández
cd01014d79 notification 2024-09-04 22:48:39 +02:00
Víctor Losada Hernández
7ab1efb0c9 litttle message in vault 2024-09-04 22:39:30 +02:00
Trevor Buckner
eb05ac00a6 Merge pull request #3263 from 5e-Cleric/experimental-development 2024-09-04 16:24:44 -04:00
Trevor Buckner
2bc39a468f set default value for dontRenderStorage prop 2024-09-04 16:15:18 -04:00
Trevor Buckner
c735ab7c35 Fix crash on metaData tab
Hiding the `moveBrew` etc. properties when `this.state.showMoveArrows == false` means when the `metaData` tab turns off the arrows it crashes because now some functions are undefined.

Just using a whole separate property to avoid conflict.
2024-09-04 15:50:32 -04:00
Gazook89
49e072f03f Add button to toggle Preview tools
Toggles a state variable to either visible or hidden which is used to set a related class on the toolbar.  The hiding is done with CSS, just reducing the width of the toolbar and the opacity of the tools.
2024-09-04 13:54:55 -05:00
Víctor Losada Hernández
d5e367649e fix overlapping thumbnail issue 2024-09-04 12:23:21 +02:00
Víctor Losada Hernández
f10444f14a fix for storage 2 2024-09-04 12:18:35 +02:00
Víctor Losada Hernández
29d4003bd2 fix splitpane errors 2024-09-04 09:37:35 +02:00
Víctor Losada Hernández
1225e5cb6a remove storage rendering in vault 2024-09-04 09:29:47 +02:00
Víctor Losada Hernández
aab24c732e fix error managing 2024-09-04 09:25:13 +02:00
G.Ambatte
dd5d551c73 Merge branch 'master' into experimentalGitAttribs 2024-09-04 17:11:21 +12:00
Trevor Buckner
d7d690a9d1 Lint 2024-09-04 01:06:56 -04:00
Trevor Buckner
4f39222724 Change spaces to tabs 2024-09-04 00:52:08 -04:00
Trevor Buckner
a1e585ccaa Remove redundant validation check
`performSearch()` and `loadTotal()` shouldn't need a separate check for valid items if `loadPage` already does it through `validateForm`
2024-09-04 00:43:12 -04:00
Trevor Buckner
373a627c14 With unneeded state gone, can rename back to title, author, etc.
No longer naming conflict with state and function parameters. We can go back to the shorter names
2024-09-04 00:35:27 -04:00
Trevor Buckner
a7cb73b02e Remove unused update in loadPage
Now `update` is unused; can remove that parameter.
2024-09-04 00:20:18 -04:00
Trevor Buckner
cd3e517b03 Remove setPageState in loadPage. Already occurs in performSearch()
`performSearch` will set PageState whether `update` is true or not, so this line here is not doing anything.
2024-09-04 00:18:35 -04:00
Trevor Buckner
ef201409d9 rename setPage to setPageState (match pageState name) 2024-09-03 23:55:54 -04:00
Trevor Buckner
e3ef93f03a Alignment 2024-09-03 23:54:52 -04:00
G.Ambatte
aa90513825 Update gitattributes 2024-09-04 15:46:00 +12:00
Trevor Buckner
1990064be4 Tidy findTotal 2024-09-03 23:44:43 -04:00
Trevor Buckner
44099c813c Fix err is not defined. Remove extra console.error (central error handler already prints the error) 2024-09-03 23:44:24 -04:00
dependabot[bot]
8f18601c2e Bump mongoose from 8.6.0 to 8.6.1
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.6.0 to 8.6.1.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.6.0...8.6.1)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-04 03:39:03 +00:00
dependabot[bot]
db02f88287 Bump eslint-plugin-react from 7.35.1 to 7.35.2
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.35.1 to 7.35.2.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.35.1...v7.35.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-04 03:38:40 +00:00
Trevor Buckner
56185e2a1c Tidy findBrews 2024-09-03 23:11:10 -04:00
Trevor Buckner
590318ff1d Simplify rendererConditions 2024-09-03 22:58:50 -04:00
Víctor Losada Hernández
48a5a70d2e z-index doesn't work with static positioning 2024-09-04 00:17:59 +02:00
Víctor Losada Hernández
1c1901c90a fix thumbnail over text 2024-09-04 00:16:15 +02:00
Víctor Losada Hernández
ebae351033 remove unnecesary state 2024-09-04 00:11:58 +02:00
Víctor Losada Hernández
e54d81ceef small css fixes 2024-09-03 23:28:33 +02:00
Víctor Losada Hernández
849da23829 bring back thumbnails! 2024-09-03 23:17:33 +02:00
Víctor Losada Hernández
1e36e63ed6 bring back the comma! 2024-09-03 23:07:23 +02:00
Víctor Losada Hernández
abb2d57879 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-09-03 22:58:05 +02:00
Víctor Losada Hernández
52779eec35 Merge branch 'experimental-development' of https://github.com/5e-Cleric/homebrewery into experimental-development 2024-09-03 22:56:49 +02:00
Víctor Losada Hernández
9e694e5e46 move email catching to api 2024-09-03 22:56:45 +02:00
Víctor Losada Hernández
321b8a0696 Merge pull request #3699 from Gazook89/Focus-Editor-After-Switch
Set Focus on Editor after Tab Switches
2024-09-03 22:37:01 +02:00
Víctor Losada Hernández
f2563e436f Merge branch 'master' into Focus-Editor-After-Switch 2024-09-03 22:34:30 +02:00
Gazook89
3c6f49aa0a Move focus method to handleViewChange 2024-09-03 14:48:45 -05:00
Trevor Buckner
9bc5701006 Indent 2024-09-03 14:18:17 -04:00
Trevor Buckner
a3a5f749ab Merge pull request #3700 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.35.1
Bump eslint-plugin-react from 7.35.0 to 7.35.1
2024-09-03 14:10:20 -04:00
dependabot[bot]
36b026d89e Bump eslint-plugin-react from 7.35.0 to 7.35.1
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.35.0 to 7.35.1.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.35.0...v7.35.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-03 18:09:47 +00:00
Trevor Buckner
dbd4a5c490 Merge pull request #3686 from G-Ambatte/v3.14.3
Up version to v3.14.3
2024-09-03 14:08:29 -04:00
Trevor Buckner
0d95c48988 Merge branch 'master' into v3.14.3 2024-09-03 14:08:06 -04:00
Trevor Buckner
0d40f4eb16 Small Rewording 2024-09-03 14:06:54 -04:00
Trevor Buckner
6234943ffd Merge pull request #3698 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-jest-28.8.2
Bump eslint-plugin-jest from 28.8.0 to 28.8.2
2024-09-03 13:52:41 -04:00
dependabot[bot]
702f55bdbd Bump eslint-plugin-jest from 28.8.0 to 28.8.2
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 28.8.0 to 28.8.2.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.8.0...v28.8.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-03 17:35:36 +00:00
Trevor Buckner
859117cdf8 Merge pull request #3691 from naturalcrit/dependabot/npm_and_yarn/googleapis/drive-8.14.0
Bump @googleapis/drive from 8.13.1 to 8.14.0
2024-09-03 13:34:22 -04:00
Víctor Losada Hernández
7474605b93 rename 2 2024-09-03 15:58:31 +02:00
Víctor Losada Hernández
00a83ec16e renaming to make more clear 2024-09-03 15:54:53 +02:00
Gazook89
afa1e7974a Set focus on editor after tab switch
This sets the focus on the editor (and thus reveals cursor position) between editor changes (style to text to meta and back).
2024-09-02 21:07:19 -05:00
Víctor Losada Hernández
1517c00132 error logging to vault 2024-09-01 19:39:00 +02:00
Víctor Losada Hernández
6d24908465 now yes fixed 2024-09-01 19:31:43 +02:00
Víctor Losada Hernández
fd2d1f1ce2 fix little bug 2024-09-01 19:21:40 +02:00
Víctor Losada Hernández
226ad49663 renaming to keep some consistency 2024-09-01 19:12:25 +02:00
Víctor Losada Hernández
e830c51a16 add spacing to link 2024-09-01 11:22:25 +02:00
Víctor Losada Hernández
b6e904c9c8 "Rename searchButtonRef to submitButtonRef and update references" 2024-09-01 11:19:00 +02:00
Víctor Losada Hernández
3fc2e5202e rest of the suggested changes 2024-09-01 11:14:09 +02:00
Víctor Losada Hernández
f0b447866c suggested changes 2 2024-09-01 11:10:46 +02:00
Víctor Losada Hernández
c528c8639a title attribute to hidden authors 2024-08-31 23:21:14 +02:00
Víctor Losada Hernández
47d8bb20d2 hide usernames with emails 2024-08-31 23:12:24 +02:00
Víctor Losada Hernández
bb08aed1a8 move some css to prevent affecting brew cards 2024-08-31 22:43:54 +02:00
Víctor Losada Hernández
9a2f18fc0d provide error code text 2024-08-31 22:38:03 +02:00
Víctor Losada Hernández
df21f978df bring back throws 2024-08-31 22:34:04 +02:00
Víctor Losada Hernández
fb8c4c5c44 all sugggested changes 2024-08-31 22:28:29 +02:00
Víctor Losada Hernández
19102db23a indent with tabs 2024-08-31 22:11:43 +02:00
Víctor Losada Hernández
8d2a9ed9cb adress app.js changes requested 2024-08-31 22:08:21 +02:00
David Bolack
6f837980eb All Snippet entries that have subsnippets but not generators. 2024-08-31 13:54:52 -05:00
Víctor Losada Hernández
a0010c9c84 "Moved error message styles from .searchButton to body, and removed duplicate styles." 2024-08-31 19:39:01 +02:00
Víctor Losada Hernández
f7c3e81b7b "Added new route for '/vault' and updated catch-all for invalid routes" 2024-08-31 19:35:44 +02:00
Víctor Losada Hernández
c7f695e86a Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-08-31 19:21:06 +02:00
Víctor Losada Hernández
e6e220fbec reposition button 2024-08-31 19:19:47 +02:00
Víctor Losada Hernández
8658a6a97a styling 2024-08-31 19:13:08 +02:00
Víctor Losada Hernández
cd94857b13 "Refactor VaultPage component: remove unnecessary whitespace, reformat code, and reorganize tips and tricks section" 2024-08-31 18:59:32 +02:00
Víctor Losada Hernández
3825bcbbfb "Simplified brewsQuery construction in buildBrewsQuery function" 2024-08-31 18:41:36 +02:00
David Bolack
82f2d0254f Merge branch 'master' into Issue_241_Part_II
Clean up a small bit of linting in the pr related functions.
2024-08-31 11:11:22 -05:00
David Bolack
5cf8715dea Merge branch 'master' into Issue_1958 2024-08-31 11:07:45 -05:00
Víctor Losada Hernández
981e7986ce Added className='renderer' to two input elements in vaultPage.jsx and added CSS rules for .renderer in vaultPage.less to display an error message when no checkboxes are checked. 2024-08-31 16:20:46 +02:00
Víctor Losada Hernández
849e5d5d1a Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimentalNotificationDB 2024-08-31 13:15:55 +02:00
Víctor Losada Hernández
188090ee45 revert themes.json 2024-08-31 13:15:11 +02:00
Víctor Losada Hernández
d352b76efe join styles and lint 2024-08-31 13:12:53 +02:00
Víctor Losada Hernández
e88272c684 "Refactor admin UI components: update class names, element types, and nesting in admin.jsx, notificationLookup.jsx, and notificationUtils.jsx" 2024-08-31 12:51:06 +02:00
Víctor Losada Hernández
10ce696333 basic styles 2024-08-31 12:50:53 +02:00
Víctor Losada Hernández
4488fe36db "Refactored notification lookup and management functionality in admin API and model, added new endpoints for getting all notifications and deleting a notification by dismiss key." 2024-08-31 12:17:12 +02:00
Víctor Losada Hernández
c79765396d add notif working 2024-08-31 00:04:44 +02:00
Víctor Losada Hernández
36549f3224 "Added 'required' attribute to several form input fields in NotificationAdd component." 2024-08-30 20:25:39 +02:00
dependabot[bot]
89583528c2 Bump @googleapis/drive from 8.13.1 to 8.14.0
Bumps [@googleapis/drive](https://github.com/googleapis/google-api-nodejs-client) from 8.13.1 to 8.14.0.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Changelog](https://github.com/googleapis/google-api-nodejs-client/blob/main/release-please-config.json)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/drive-v8.13.1...drive-v8.14.0)

---
updated-dependencies:
- dependency-name: "@googleapis/drive"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-30 03:53:37 +00:00
David Bolack
2a366c3053 Update ToC Style snippets for better specificity 2024-08-29 17:51:59 -05:00
David Bolack
de8bd67e07 Add toggles for global Toc changes. 2024-08-29 17:44:45 -05:00
Víctor Losada Hernández
dcfc510ce8 more page sizes + more background options 2024-08-30 00:22:47 +02:00
Víctor Losada Hernández
e81a9dab1f add good stylings, and lint 2024-08-29 23:40:13 +02:00
Víctor Losada Hernández
65759e18bd clean inputs 2024-08-29 23:39:54 +02:00
G.Ambatte
f458b98dcf Merge branch 'master' into experimentalDeploymentIdentification 2024-08-29 21:31:55 +12:00
G.Ambatte
cc7fe99760 Initial functionality pass 2024-08-29 21:26:24 +12:00
Víctor Losada Hernández
78642e514d revert console log 2024-08-29 10:47:38 +02:00
Víctor Losada Hernández
4edbfa10b5 log config vars 2024-08-29 10:45:36 +02:00
G.Ambatte
e588e68313 Merge branch 'master' into v3.14.3 2024-08-29 17:47:36 +12:00
G.Ambatte
e4c2ffe973 Add image wrap icon fix 2024-08-29 17:46:23 +12:00
Trevor Buckner
c41116e6c8 Merge pull request #3687 from G-Ambatte/fixImageWrapIcons
Fix Image Wrap icons
2024-08-29 01:30:17 -04:00
G.Ambatte
b66ac43b35 Fix Image Wrap icons 2024-08-29 17:23:18 +12:00
G.Ambatte
c30404804d Fix typo 2024-08-29 17:20:39 +12:00
G.Ambatte
6b10e1aacb Very important F 2024-08-29 17:19:47 +12:00
G.Ambatte
e6185879c8 Up version to v3.14.3 2024-08-29 17:17:12 +12:00
Trevor Buckner
e776e5e054 Merge pull request #3684 from naturalcrit/FixTableInterruptors 2024-08-29 00:47:00 -04:00
Trevor Buckner
04bbb3d615 Merge branch 'master' into FixTableInterruptors 2024-08-29 00:44:46 -04:00
Trevor Buckner
5d1f589b07 Merge pull request #3685 from naturalcrit/dependabot/npm_and_yarn/marked-extended-tables-1.0.10 2024-08-29 00:44:38 -04:00
dependabot[bot]
ce5f093945 Bump marked-extended-tables from 1.0.9 to 1.0.10
Bumps [marked-extended-tables](https://github.com/calculuschild/marked-extended-tables) from 1.0.9 to 1.0.10.
- [Release notes](https://github.com/calculuschild/marked-extended-tables/releases)
- [Changelog](https://github.com/calculuschild/marked-extended-tables/blob/main/release.config.cjs)
- [Commits](https://github.com/calculuschild/marked-extended-tables/commits)

---
updated-dependencies:
- dependency-name: marked-extended-tables
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-29 04:42:49 +00:00
Trevor Buckner
371e464eb2 Merge branch 'master' into FixTableInterruptors 2024-08-29 00:30:07 -04:00
Trevor Buckner
804d714473 Add regex to detect when to interrupt a table 2024-08-29 00:20:47 -04:00
Trevor Buckner
8d00389aa2 Merge pull request #3683 from naturalcrit/dependabot/npm_and_yarn/marked-extended-tables-1.0.9 2024-08-29 00:19:42 -04:00
dependabot[bot]
d64787168b Bump marked-extended-tables from 1.0.8 to 1.0.9
Bumps [marked-extended-tables](https://github.com/calculuschild/marked-extended-tables) from 1.0.8 to 1.0.9.
- [Release notes](https://github.com/calculuschild/marked-extended-tables/releases)
- [Changelog](https://github.com/calculuschild/marked-extended-tables/blob/main/release.config.cjs)
- [Commits](https://github.com/calculuschild/marked-extended-tables/commits)

---
updated-dependencies:
- dependency-name: marked-extended-tables
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-29 04:17:07 +00:00
Trevor Buckner
49a1a74263 Merge pull request #3681 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.6.0 2024-08-29 00:04:39 -04:00
dependabot[bot]
2636635397 Bump mongoose from 8.5.4 to 8.6.0
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.4 to 8.6.0.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.5.4...8.6.0)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-29 04:01:06 +00:00
Trevor Buckner
c49c620ce1 Merge pull request #3680 from naturalcrit/dependabot/npm_and_yarn/stylelint-16.9.0 2024-08-29 00:00:07 -04:00
dependabot[bot]
0b00162590 Bump stylelint from 16.8.2 to 16.9.0
Bumps [stylelint](https://github.com/stylelint/stylelint) from 16.8.2 to 16.9.0.
- [Release notes](https://github.com/stylelint/stylelint/releases)
- [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint/stylelint/compare/16.8.2...16.9.0)

---
updated-dependencies:
- dependency-name: stylelint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-29 03:33:22 +00:00
David Bolack
03f8fc83ee Add snippets for page Numbering updates
Adds options to add skipCounting and ResetCounting classes
2024-08-28 21:33:32 -05:00
Trevor Buckner
5e19bdaee7 Merge pull request #3678 from dbolack-ab/accursedKeys 2024-08-28 22:24:50 -04:00
David Bolack
089dcb942b Merge branch 'master' into actualPageNumber 2024-08-28 21:23:22 -05:00
David Bolack
a4f30d687d Merge branch 'master' into Issue_241_Part_II 2024-08-28 21:17:10 -05:00
David Bolack
5e8f74b9bc Merge branch 'master' into Issue_1958 2024-08-28 21:09:07 -05:00
David Bolack
bda8be6ec1 Remove stray console.log 2024-08-28 20:54:50 -05:00
David Bolack
132a7d1f53 A temporary, imperfect fix for the jump hotkeys 2024-08-28 20:48:33 -05:00
Víctor Losada Hernández
b39e8eea16 Merge branch 'experimentalNotificationDB' of https://github.com/G-Ambatte/homebrewery; branch 'master' of https://github.com/naturalcrit/homebrewery into experimentalNotificationDB 2024-08-29 00:24:22 +02:00
Víctor Losada Hernández
0c6c0c9fd6 use actual inputs and textarea with good attributes 2024-08-29 00:23:22 +02:00
Víctor Losada Hernández
51d3d11bff "Refactor notification utils components to use React Hooks instead of createClass" 2024-08-29 00:01:02 +02:00
Víctor Losada Hernández
46882c4fb4 add error logging on admin route 2024-08-29 00:00:55 +02:00
Trevor Buckner
2dbb92a37e Merge pull request #3677 from 5e-Cleric/account-page-handling-of-invalid-user
Account page handling of invalid user
2024-08-28 17:07:52 -04:00
Trevor Buckner
a124bd8657 I'm dumb. 2024-08-28 16:59:22 -04:00
Víctor Losada Hernández
760c1a9e8c Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimentalNotificationDB 2024-08-28 22:28:24 +02:00
Trevor Buckner
5323e6ca7a Merge branch 'master' into account-page-handling-of-invalid-user 2024-08-28 15:25:12 -04:00
Trevor Buckner
8423c48fd1 Slight rewording and add a period 2024-08-28 15:24:50 -04:00
Trevor Buckner
e8aceac133 Move check for account up a little 2024-08-28 15:21:43 -04:00
Trevor Buckner
5a692a74c5 Merge pull request #3660 from naturalcrit/imageWrappin
Image wrapping
2024-08-28 15:18:50 -04:00
Víctor Losada Hernández
6436e62ec0 set up error page 2024-08-28 21:10:28 +02:00
Víctor Losada Hernández
c9947d7f91 handle invalid account in account page, redirect to home 2024-08-28 20:42:53 +02:00
Trevor Buckner
3b3127248b Merge branch 'master' into imageWrappin 2024-08-28 14:37:26 -04:00
Trevor Buckner
1d2355e802 Merge pull request #3674 from naturalcrit/dependabot/npm_and_yarn/googleapis/drive-8.13.1
Bump @googleapis/drive from 8.13.0 to 8.13.1
2024-08-28 09:47:22 -04:00
dependabot[bot]
b85bb7bdd4 Bump @googleapis/drive from 8.13.0 to 8.13.1
Bumps [@googleapis/drive](https://github.com/googleapis/google-api-nodejs-client) from 8.13.0 to 8.13.1.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Changelog](https://github.com/googleapis/google-api-nodejs-client/blob/main/release-please-config.json)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/drive-v8.13.0...drive-v8.13.1)

---
updated-dependencies:
- dependency-name: "@googleapis/drive"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-28 03:42:23 +00:00
Trevor Buckner
a016bfd133 Merge pull request #3673 from Gazook89/Fix-Toolbar-Positioning
Revert toolbar positioning change
2024-08-27 13:03:12 -04:00
Trevor Buckner
63fa747fd7 Merge branch 'master' into Fix-Toolbar-Positioning 2024-08-27 13:03:06 -04:00
Gazook89
a7ddeafd06 revert change 2024-08-27 11:59:29 -05:00
Trevor Buckner
81e6cae99d Merge pull request #3670 from 5e-Cleric/v3.14.2
up to v3.14.2
2024-08-27 12:00:38 -04:00
Trevor Buckner
be0db1770d Reword to describe the fix, rather than the PR title 2024-08-27 11:55:41 -04:00
Trevor Buckner
f905a62b6c Merge branch 'master' into v3.14.2 2024-08-27 11:47:47 -04:00
Trevor Buckner
35ca31cf43 Merge pull request #3671 from Gazook89/Fix-Toolbar-Positioning
Small Patch for Toolbar Positioning
2024-08-27 11:47:24 -04:00
Trevor Buckner
0ce3ac9be2 Merge branch 'master' into Fix-Toolbar-Positioning 2024-08-27 11:27:36 -04:00
Trevor Buckner
7cdf1c93cf Merge pull request #3665 from Gazook89/Fill-Pane-Buttons
VIEWER TOOLS PART 2 - Zoom to Fit, Fit to Width
2024-08-27 11:26:56 -04:00
Gazook89
a7c4b78ec8 set position relative, remove padding 2024-08-27 09:03:24 -05:00
Gazook89
aa321fe2c3 Merge branch 'master' into Fill-Pane-Buttons 2024-08-27 08:43:19 -05:00
Gazook89
7bc0af9a8c utilize Infinity and reduce() 2024-08-27 08:42:45 -05:00
Víctor Losada Hernández
69475833e6 "Update changelog.md with new hotkeys and fix for reload clobbering modified fresh clones" 2024-08-27 15:23:17 +02:00
Víctor Losada Hernández
7dce3b3de5 up to v3.14.2 2024-08-27 10:41:53 +02:00
Trevor Buckner
183687d676 Merge pull request #3075 from G-Ambatte/addCSSRoute-#1097
Add route to get brew styling
2024-08-26 20:04:46 -04:00
Trevor Buckner
786acc7a1c Merge branch 'master' into addCSSRoute-#1097 2024-08-26 20:01:45 -04:00
Trevor Buckner
3d3ad3f284 Small tweaks 2024-08-26 19:58:28 -04:00
Trevor Buckner
a6a1d70abc Merge pull request #3669 from naturalcrit/dependabot/npm_and_yarn/eslint-9.9.1
Bump eslint from 9.9.0 to 9.9.1
2024-08-26 17:39:44 -04:00
dependabot[bot]
73461d6372 Bump eslint from 9.9.0 to 9.9.1
Bumps [eslint](https://github.com/eslint/eslint) from 9.9.0 to 9.9.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.9.0...v9.9.1)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 21:35:52 +00:00
Trevor Buckner
e56c6a5085 Merge pull request #3668 from naturalcrit/dependabot/npm_and_yarn/superagent-10.1.0
Bump superagent from 9.0.2 to 10.1.0
2024-08-26 17:34:39 -04:00
Trevor Buckner
f8f0280f8c Merge branch 'master' into dependabot/npm_and_yarn/superagent-10.1.0 2024-08-26 17:27:58 -04:00
Trevor Buckner
4e393779ac Merge pull request #3644 from G-Ambatte/fixEmojiFolding-#3604
Prevent styling of lines inside folded sections
2024-08-26 17:26:01 -04:00
Trevor Buckner
5671728c97 Change filter to some
`some` stops once it finds a true case; `filter` has to process the whole list of folds first.
2024-08-26 17:23:44 -04:00
Gazook89
e06611a90f set all zoom buttons to use handleZoomButton
All zoom buttons run through same handler now.

They no longer take only the delta of the current zoom and desired zoom-- they take the actual desired zoom.

calculateZoom is now calculateChange, to help get the desired delta.
2024-08-26 16:16:13 -05:00
Gazook89
7b767368df Change icons to mask-image
Removes icons as components, uses mask-image instead.

Sets a size on the .fac icons to 1em so by default they are 1em and retain their aspect ratio.

rename the icon files for consistency.
2024-08-26 15:51:35 -05:00
Trevor Buckner
d59c6be359 Merge branch 'master' into fixEmojiFolding-#3604 2024-08-26 16:34:06 -04:00
dependabot[bot]
0d564dd0bf Bump superagent from 9.0.2 to 10.1.0
Bumps [superagent](https://github.com/ladjs/superagent) from 9.0.2 to 10.1.0.
- [Release notes](https://github.com/ladjs/superagent/releases)
- [Changelog](https://github.com/ladjs/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/ladjs/superagent/compare/v9.0.2...v10.1.0)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 03:57:55 +00:00
Trevor Buckner
ef6e1e1782 Merge pull request #3667 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.5.4
Bump mongoose from 8.5.3 to 8.5.4
2024-08-25 23:56:46 -04:00
dependabot[bot]
b2f5e39256 Bump mongoose from 8.5.3 to 8.5.4
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.3 to 8.5.4.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.5.3...8.5.4)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 03:55:31 +00:00
Víctor Losada Hernández
762de62aa6 Merge branch 'master' into addCSSRoute-#1097 2024-08-25 13:21:37 +02:00
Trevor Buckner
d4d27aab6a Merge branch 'master' into Fill-Pane-Buttons 2024-08-24 23:59:19 -04:00
Trevor Buckner
1803c89a23 Merge pull request #3499 from 5e-Cleric/pdf-tools
Viewer tools
2024-08-24 23:58:10 -04:00
Trevor Buckner
4b0b56dd35 Lint the jsx files 2024-08-24 23:55:17 -04:00
Trevor Buckner
bf6eae7b3c Simplify some logic in Toolbar 2024-08-24 23:54:09 -04:00
Trevor Buckner
3377d6645d Tidy up brewRenderer 2024-08-24 23:53:44 -04:00
Trevor Buckner
5069eadd0a Manual tidying of .less files 2024-08-24 23:53:07 -04:00
Trevor Buckner
7a5b0b32c4 restore deleted line from helpers.js 2024-08-24 23:26:45 -04:00
Gazook89
2b79583e8c Merge branch 'pr/3499' into View-Modes 2024-08-24 22:03:06 -05:00
Gazook89
35a0a12f16 Merge branch 'pr/3499' into Fill-Pane-Buttons 2024-08-24 22:02:56 -05:00
Gazook89
504bb78a8d switching padding to margin
using `padding-top` was breaking the navbar dropdowns (they would lose focus).
2024-08-24 22:02:43 -05:00
Gazook89
609b40e84c Merge branch 'pr/3499' into View-Modes 2024-08-24 21:28:39 -05:00
Gazook89
94ae33d328 Merge branch 'pr/3499' into Fill-Pane-Buttons 2024-08-24 21:28:13 -05:00
Gazook89
690c683943 select text when clicking into page input 2024-08-24 09:08:19 -05:00
Gazook89
3acf90dfdb Add handlePageChange() to control input
Reintroducing handlePageChange() method to handle the page input separately from the scroll function.  It tests the regex pattern on the string, parses to integer, and sets pageNum state.

scrollToPage also now sets the pageNum state after performing the scroll so the input box matches the new current page.
2024-08-24 09:05:43 -05:00
David Bolack
f24e47785c Merge branch 'master' into Issue_241_Part_II 2024-08-24 00:48:52 -05:00
David Bolack
e27e61aaca Bind livescrolling when done via scrollbars. 2024-08-24 00:47:06 -05:00
Gazook89
07c574fa42 Merge branch 'Fill-Pane-Buttons' into View-Modes 2024-08-23 23:26:24 -05:00
Gazook89
6bb5d04f07 round the calculated zoom level 2024-08-23 23:02:04 -05:00
Gazook89
b0b1f7fd0b update method calls for zoom buttons
update method names in onClick events to match latest changes to the branch this builds from.
2024-08-23 22:58:43 -05:00
Gazook89
c25bf95a66 Merge branch 'pr/3499' into Fill-Pane-Buttons 2024-08-23 22:56:37 -05:00
Gazook89
370c480670 Merge branch 'master' into pr/3499 2024-08-23 22:55:13 -05:00
Gazook89
a351013359 remove some odd if statement in onChange 2024-08-23 22:54:29 -05:00
Gazook89
1f86b4c3d0 add mainRef back in
This was previously in the .pageInfo widget, probably not for any good reason, but I'm moving it to the popups div for probably not a good reason.

It's used to get the parent .pane div, and pull its `height` value which is then passed to the `.brewRenderer` div to set the height.

I tried alternate methods that would make this obsolete (CSS methods mostly), but due to some complexity am just ditching those alternatives and popping this sucker into `.popups` for now.
2024-08-23 22:41:12 -05:00
Gazook89
627a6a732b remove .ppr_msg styling
This message doesn't exist anymore (i'm pretty sure), so this is just unused styling.  Unrleated to the PR, but just minor.
2024-08-23 19:26:41 -05:00
Gazook89
77421c2950 remove .pageInfo widget in bottom of preview
page counter function is in toolbar now, so this isn't necessary.
2024-08-23 19:25:49 -05:00
Gazook89
f3ed174b0e eslint and stylelint
stylelint has a problem with the `:horizontal` pseudo selector in brewRenderer.jsx, which is being used to apply some styling to the custom scrollbars.  As far as i can tell, the selector is not standards-track, so that is probably why.  Not sure if we want to adjsut our stylelint config to allow it?
2024-08-23 19:16:59 -05:00
Gazook89
977d0ea73a eslint 2024-08-23 19:05:23 -05:00
Gazook89
04effa2150 removed whitepsace 2024-08-23 18:59:32 -05:00
Gazook89
7f694e6ca7 fold handlePageChange directly into input onChange
Moved the single-line handler to operate directly in the onChange handler of the input that is calling it.

Considered doing the same with handleZoomChange, but that handler is used by two buttons rather than just one.
2024-08-23 18:58:51 -05:00
Gazook89
769a03916b rename pageInput state variable to pageNum 2024-08-23 18:48:36 -05:00
Gazook89
e3c90a8295 unset padding on brewRenderer in @print
Fixes an issue with the padding being reflected in pdfs as a white stripe at the top.
2024-08-23 18:45:08 -05:00
Gazook89
561ff6283a remove redundant handleScroll() method
handleScroll is replaced by getCurrentPage(), which effectively does the same thing.  The math is slightly different, though very similar, and result seems to be the same.
2024-08-23 18:33:14 -05:00
Víctor Losada Hernández
5e69718f4f Merge branch 'master' into imageWrappin 2024-08-23 23:30:37 +02:00
Víctor Losada Hernández
ca5a7a1dbb Merge branch 'master' into addCSSRoute-#1097 2024-08-23 23:16:19 +02:00
Víctor Losada Hernández
505ac0c1d5 Merge pull request #3515 from dbolack-ab/Issue_1430_Unique_HeaderIDs
Create globally unique Header IDs when marked parses.
2024-08-23 23:12:02 +02:00
Víctor Losada Hernández
987d1c881b Merge branch 'master' of https://github.com/naturalcrit/homebrewery into Issue_1430_Unique_HeaderIDs 2024-08-23 23:08:20 +02:00
Gazook89
f34107ee1d fix typo 2024-08-23 15:06:48 -05:00
Gazook89
2246944dd2 Remove duplicate ErrorBar/popups tray
Removed duplicated components.

Restyled the popups to accomodate extra height of viewer tools.
2024-08-23 14:40:19 -05:00
Gazook89
960ecae861 setup styles for different view modes
added styles for different modes-- basically a grid for 'facing' and flex for 'flow'.
2024-08-23 14:29:52 -05:00
Gazook89
49a4daa8f6 useEffect hook to update view after mode select
utilize useEffect hook to trigger render when the mode state is changed.

Move modes array to top level array, and change 'book-mode' to 'facing', and add 'flow' mode.

toggle modes as class names in .pages div, which are each styled as required.
2024-08-23 14:29:02 -05:00
Víctor Losada Hernández
1f41745d2b "Refactored Snippetbar component: updated JSX structure, added div wrapper for snippets, changed CSS styles for editors and snippets" 2024-08-23 13:37:12 +02:00
Víctor Losada Hernández
1602f0af37 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into snippet-bar-wrapping 2024-08-23 13:37:03 +02:00
Gazook89
375c54016c Get basic function worked out
Adds `setBookMode()` which toggles a className on `.pages`.  The `.book-mode` class sets display to grid, and the first child/page to start at the second slot of the book arrangement.
2024-08-23 00:32:30 -05:00
Trevor Buckner
717ced28d6 Merge pull request #3662 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.25.4
Bump @babel/preset-env from 7.25.3 to 7.25.4
2024-08-23 01:17:02 -04:00
dependabot[bot]
fb836df8d5 Bump @babel/preset-env from 7.25.3 to 7.25.4
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.25.3 to 7.25.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.4/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-23 05:03:02 +00:00
Trevor Buckner
fba08262d3 Merge pull request #3661 from naturalcrit/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.25.4
Bump @babel/plugin-transform-runtime from 7.24.7 to 7.25.4
2024-08-23 01:01:49 -04:00
dependabot[bot]
56582b6b24 Bump @babel/plugin-transform-runtime from 7.24.7 to 7.25.4
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.24.7 to 7.25.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.4/packages/babel-plugin-transform-runtime)

---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-23 04:58:49 +00:00
Trevor Buckner
43e4e43c7c Merge pull request #3663 from naturalcrit/updateEsLintV9
up ESLint to v9.9
2024-08-23 00:57:34 -04:00
Trevor Buckner
3f3f113305 More typos 2024-08-23 00:54:00 -04:00
Trevor Buckner
96e23ee2ea fix accidental deletion 2024-08-23 00:52:48 -04:00
Trevor Buckner
c57c9e236b Update config file to new format 2024-08-23 00:49:36 -04:00
Gazook89
32c6224f40 remove console.log 2024-08-22 23:30:36 -05:00
Gazook89
8dadc57934 adjustment to toolbar spacing between items
testing the use of spacing to separate tool groups.  Could alternatively use a thin vertical bar.
2024-08-22 23:22:39 -05:00
Gazook89
0dc9e9ecdb Add 2 custom zoom related icons
New icons for Zoom to Fit, and Fit Width buttons.  Used SVGR online tool to create react components and then combined them.

If doing in future, be sure to set currentColor on `fill` property in the SVG itself.  Make the SVGs as closed curves only (don't rely on stroke).  set only a width property, not height.
2024-08-22 23:21:48 -05:00
Gazook89
977b871967 Combine toFit and toFill functions
Reduce overlap of the two functions and just require a 'mode' parameter.  Could like roll a 'manual' mode into this for the zoom slider, as well, but skipping for now.
2024-08-22 23:19:24 -05:00
Trevor Buckner
4fa8351f7f Merge pull request #3643 from G-Ambatte/fixMaskSkewing-#3636
Change order of operations in mask img transform
2024-08-22 22:14:46 -04:00
Trevor Buckner
fa669f32fc Merge branch 'master' into fixMaskSkewing-#3636 2024-08-22 22:12:10 -04:00
Trevor Buckner
fc294807fd Merge branch 'master' into imageWrappin 2024-08-22 22:10:11 -04:00
Trevor Buckner
a9fe516675 Merge pull request #3657 from naturalcrit/dependabot/npm_and_yarn/stylelint-config-recess-order-5.1.0
Bump stylelint-config-recess-order from 5.0.1 to 5.1.0
2024-08-22 22:09:53 -04:00
Trevor Buckner
6502847b95 Merge pull request #3648 from dbolack-ab/preservePREColons
Fix for the colons in codeblocks issue.
2024-08-22 22:09:34 -04:00
Gazook89
90dd4326e7 Add a toFit() method to fit largest page in view
Adding a real toFit() button that takes the page with the largest single dimension (height or width) and makes it fit within the pane.
2024-08-22 20:56:42 -05:00
Trevor Buckner
eeedc5f7d4 Merge branch 'master' into preservePREColons 2024-08-22 21:53:16 -04:00
Trevor Buckner
fff357d08b Make 'block-level' extension. Tweaks to pass new tests
'block-level' because it never occurs inside another block ('inline-level' always occurs inside something else); starts and stops on on its own line without anything else on the same line.
2024-08-22 21:52:40 -04:00
Trevor Buckner
e0b69dce14 add more test cases
Test a large number of breaks, and interaction with paragraphs
2024-08-22 21:49:40 -04:00
Trevor Buckner
e6c5e6451c Add more tests for edge conflicts with definition lists 2024-08-22 21:46:42 -04:00
Trevor Buckner
26866c337f Add tests to circleci 2024-08-22 21:45:44 -04:00
Gazook89
4c71987866 change the toFit method to toFill
Realized this method is filling the preview pane, and that toFit would force the zoom to show the entirety of a single page at once.
2024-08-22 15:56:23 -05:00
Gazook89
8965bb60aa add a toFit() method to determine zoom change
Adds a toFit() method to determine the delta/change needed to the current zoomLevel to fit the page to the pane, so that the widest page fits just inside the pane.
2024-08-22 15:52:52 -05:00
Gazook89
64fb032622 fix className 2024-08-22 15:51:16 -05:00
Trevor Buckner
073076e011 Merge pull request #3654 from naturalcrit/RerouteInvalidPaths
Add catch-all for invalid paths
2024-08-22 16:38:25 -04:00
Trevor Buckner
71b505d55b Merge branch 'master' into RerouteInvalidPaths 2024-08-22 16:37:55 -04:00
Trevor Buckner
dc7d877e6f Add snippets and icons 2024-08-22 16:35:48 -04:00
Trevor Buckner
40ab2c2283 rearrange code 2024-08-22 14:24:33 -04:00
Trevor Buckner
d8f0618691 Fix variables tests for same reason 2024-08-22 13:20:07 -04:00
Trevor Buckner
955b34b637 Fix tests to account for --HB_src variable presence 2024-08-22 13:12:40 -04:00
Trevor Buckner
8dea2ca9fb wrapLeft and wrapRight classes to automatically apply wrapping 2024-08-22 12:47:26 -04:00
Trevor Buckner
696bcd4367 Expose src url in --HB_src
Decided to do this for *all* images, not just those being injected. In case someone wants to automatically apply wrapping to images inside a stat block, etc.
2024-08-22 12:46:56 -04:00
Trevor Buckner
d70c5a6fe3 Merge pull request #3658 from naturalcrit/UpdateMarkedHelperFunctions
Update `cleanURL` helper function to match later Marked version
2024-08-22 11:53:51 -04:00
Trevor Buckner
645c9a122c Update cleanURL helper function to match later Marked version 2024-08-22 11:51:24 -04:00
Trevor Buckner
b774c89bdb Merge branch 'master' into RerouteInvalidPaths 2024-08-22 10:41:00 -04:00
dependabot[bot]
c75ebb36cb Bump stylelint-config-recess-order from 5.0.1 to 5.1.0
Bumps [stylelint-config-recess-order](https://github.com/stormwarning/stylelint-config-recess-order) from 5.0.1 to 5.1.0.
- [Release notes](https://github.com/stormwarning/stylelint-config-recess-order/releases)
- [Changelog](https://github.com/stormwarning/stylelint-config-recess-order/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stormwarning/stylelint-config-recess-order/compare/v5.0.1...v5.1.0)

---
updated-dependencies:
- dependency-name: stylelint-config-recess-order
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-22 03:10:12 +00:00
David Bolack
1c03138968 Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-08-21 21:23:09 -05:00
David Bolack
1313772adc Merge branch 'master' into preservePREColons 2024-08-21 21:21:06 -05:00
David Bolack
695293333f Fix merge 2024-08-21 21:19:10 -05:00
David Bolack
5431d3ed9b Merge branch 'master' into Issue_241_Part_II 2024-08-21 21:03:26 -05:00
David Bolack
fc9821a6c4 Merge branch 'master' into actualPageNumber 2024-08-21 20:55:21 -05:00
Víctor Losada Hernández
fb06ae0d03 Merge branch 'master' into pdf-tools 2024-08-21 23:07:25 +02:00
G.Ambatte
e952e05b79 Merge branch 'master' into fixMaskSkewing-#3636 2024-08-22 08:45:26 +12:00
Trevor Buckner
c020297d78 Merge pull request #3655 from naturalcrit/dependabot/npm_and_yarn/googleapis/drive-8.13.0
Bump @googleapis/drive from 8.11.1 to 8.13.0
2024-08-21 10:34:35 -04:00
dependabot[bot]
8ea7d3dc8f Bump @googleapis/drive from 8.11.1 to 8.13.0
Bumps [@googleapis/drive](https://github.com/googleapis/google-api-nodejs-client) from 8.11.1 to 8.13.0.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Changelog](https://github.com/googleapis/google-api-nodejs-client/blob/main/release-please-config.json)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/drive-v8.11.1...drive-v8.13.0)

---
updated-dependencies:
- dependency-name: "@googleapis/drive"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-21 03:14:46 +00:00
Gazook89
051eed0e83 restructure html, eliminate .tool divs
Treat each input and button as a direct child of the `.group` class, removing the intermediate div and reassign the `tool` classname to those inputs and buttons.  One item, the current / total page "set", is wrapped in a .tool div because they should be considered one item (even within the .group container).

And then a bunch of CSS adjustments to match the new structure.
2024-08-20 21:08:07 -05:00
Gazook89
cdc2ffeff4 remove if statement that shouldn't occur at all
Removing a redundant if/else that shouldn't be possible now that the currentPage is clamped between 1 and totalPages.
2024-08-20 20:18:54 -05:00
Trevor Buckner
dedf9e0be9 Merge pull request #3630 from dbolack-ab/FalsePaths
Prevent loading of undefined renderer or theme theme bundle.
2024-08-20 17:33:41 -04:00
Trevor Buckner
0cc001fe94 Merge branch 'master' into FalsePaths 2024-08-20 17:33:30 -04:00
Trevor Buckner
0f969ce383 Add catch-all for invalid paths
res.route is the currently-matched route. If nothing has been matched by this point (route = undefined), we have an invalid route.
2024-08-20 17:11:50 -04:00
Gazook89
83244485ab Move scrollToPage to toolbar component
Keeps toolbar functions within the toolbar component and reduces props that need to be sent down.
2024-08-20 15:15:36 -05:00
Trevor Buckner
defbc716c0 Merge pull request #3633 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.5.3
Bump mongoose from 8.5.2 to 8.5.3
2024-08-20 16:09:07 -04:00
Trevor Buckner
1803dfdeb1 Merge branch 'master' into dependabot/npm_and_yarn/mongoose-8.5.3 2024-08-20 15:54:55 -04:00
Trevor Buckner
787d50f17c Merge pull request #3483 from dbolack-ab/Issue_241
Add Jump-To hotkeys
2024-08-20 15:54:42 -04:00
David Bolack
925d934892 Merge branch 'master' into preservePREColons 2024-08-20 14:02:46 -05:00
David Bolack
e45bcf76ce Merge branch 'master' into Issue_241 2024-08-20 13:49:02 -05:00
David Bolack
54d5dbf992 Pruning 2024-08-20 13:47:32 -05:00
David Bolack
bb18ed7eda Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-08-20 13:41:29 -05:00
David Bolack
fa63f1d4d5 Merge branch 'master' into Issue_241_Part_II 2024-08-20 13:38:47 -05:00
David Bolack
a6969a9ce2 Merge branch 'master' into actualPageNumber 2024-08-20 13:38:26 -05:00
dependabot[bot]
f8895721fc Bump mongoose from 8.5.2 to 8.5.3
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.5.2 to 8.5.3.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.5.2...8.5.3)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-20 18:36:57 +00:00
David Bolack
ba340f033a Merge branch 'master' into preservePREColons 2024-08-20 13:36:29 -05:00
Trevor Buckner
4c30a8f6a3 Merge pull request #3641 from naturalcrit/dependabot/npm_and_yarn/stylelint-16.8.2
Bump stylelint from 16.8.1 to 16.8.2
2024-08-20 14:35:39 -04:00
David Bolack
cbcb712587 Merge branch 'master' into Issue_241 2024-08-20 13:34:47 -05:00
Trevor Buckner
187b6a9e8a Merge branch 'master' into dependabot/npm_and_yarn/stylelint-16.8.2 2024-08-20 14:27:37 -04:00
Trevor Buckner
2816a39ff9 Merge pull request #3652 from dbolack-ab/saveTheClones
Prevent reload from clobbering modified fresh clones
2024-08-20 14:27:24 -04:00
David Bolack
78c4061199 Merge branch 'master' into Issue_241_Part_II 2024-08-20 13:26:19 -05:00
David Bolack
1ad88c2fca Merge branch 'master' into actualPageNumber 2024-08-20 13:25:24 -05:00
David Bolack
9203cc2a6a Merge branch 'master' into preservePREColons 2024-08-20 13:24:24 -05:00
David Bolack
9e19ba2d4e Merge branch 'master' into saveTheClones 2024-08-20 13:22:56 -05:00
David Bolack
a706c9ff9b Merge branch 'master' into Issue_241 2024-08-20 13:22:25 -05:00
David Bolack
4957a0d2ef Flip which arror is which. 2024-08-20 13:18:48 -05:00
David Bolack
727f2bd80e use replaceState instead 2024-08-20 13:15:32 -05:00
Trevor Buckner
11790fa438 Merge branch 'master' into dependabot/npm_and_yarn/stylelint-16.8.2 2024-08-20 13:53:56 -04:00
Trevor Buckner
c4049ec5fa Merge pull request #3642 from naturalcrit/dependabot/npm_and_yarn/react-router-dom-6.26.1
Bump react-router-dom from 6.26.0 to 6.26.1
2024-08-20 13:53:35 -04:00
Trevor Buckner
02fca27f85 Merge branch 'master' into dependabot/npm_and_yarn/react-router-dom-6.26.1 2024-08-20 13:51:07 -04:00
Trevor Buckner
7f717b92fd Merge pull request #3653 from naturalcrit/dependabot/npm_and_yarn/elliptic-6.5.7
Bump elliptic from 6.5.6 to 6.5.7
2024-08-20 13:50:52 -04:00
dependabot[bot]
e2272b078b Bump elliptic from 6.5.6 to 6.5.7
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.6 to 6.5.7.
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.6...v6.5.7)

---
updated-dependencies:
- dependency-name: elliptic
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-20 17:47:02 +00:00
dependabot[bot]
01161752c6 Bump react-router-dom from 6.26.0 to 6.26.1
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.26.0 to 6.26.1.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.26.1/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-20 17:46:53 +00:00
Trevor Buckner
3237a4f2eb Merge branch 'master' into dependabot/npm_and_yarn/stylelint-16.8.2 2024-08-20 13:45:58 -04:00
Trevor Buckner
d87e07e9ba Merge pull request #3649 from naturalcrit/dependabot/npm_and_yarn/stylistic/stylelint-plugin-3.0.1
Bump @stylistic/stylelint-plugin from 3.0.0 to 3.0.1
2024-08-20 13:45:38 -04:00
dependabot[bot]
82529e0b06 Bump stylelint from 16.8.1 to 16.8.2
Bumps [stylelint](https://github.com/stylelint/stylelint) from 16.8.1 to 16.8.2.
- [Release notes](https://github.com/stylelint/stylelint/releases)
- [Changelog](https://github.com/stylelint/stylelint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint/stylelint/compare/16.8.1...16.8.2)

---
updated-dependencies:
- dependency-name: stylelint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-20 17:44:18 +00:00
dependabot[bot]
641303d1ad Bump @stylistic/stylelint-plugin from 3.0.0 to 3.0.1
Bumps [@stylistic/stylelint-plugin](https://github.com/stylelint-stylistic/stylelint-stylistic) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/stylelint-stylistic/stylelint-stylistic/releases)
- [Changelog](https://github.com/stylelint-stylistic/stylelint-stylistic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/stylelint-stylistic/stylelint-stylistic/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: "@stylistic/stylelint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-20 17:44:14 +00:00
Trevor Buckner
845c2eca76 Merge pull request #3650 from naturalcrit/dependabot/npm_and_yarn/googleapis/drive-8.11.1
Bump @googleapis/drive from 8.11.0 to 8.11.1
2024-08-20 13:42:58 -04:00
David Bolack
e957f40775 Revert previous simplification as it breaks the original purpose of this PR
Added test for inside a code block.
2024-08-20 12:17:51 -05:00
David Bolack
3985afade9 Remove need for Definition exceptios
Retool original `:` break to insert `\n\n`s between each `:` so that
the definition lists never have a chance for a mismatch.

Rename token to "hardbreak"
Add tests for hardBreaks for `:`, `::`, and `:::` which should verify it works and does not collide with definitionlists.
2024-08-20 11:46:43 -05:00
Gazook89
f5ee55d0ca keep current page number within existing page range
Make it so that if a user enters a page number higher than the total page count, it jumps them to last page.  if lower than 1, it jumps them to first page.
2024-08-19 23:40:21 -05:00
Gazook89
2cf73698e8 white space lint 2024-08-19 23:38:48 -05:00
Gazook89
28a06348ab style tool groups, minor tweaks to spacing 2024-08-19 23:15:02 -05:00
Gazook89
9510b4d097 wrap each set of toolbars into groups
Allows more styling options, including flex wrapping by group rather than individual button.
2024-08-19 23:14:45 -05:00
Gazook89
37c8ea4fd7 Add total page count and some styling
Displaying the total page count near the current page number means we can lose the bottom right toolbar entirely (the renderer could be added to top toolbar, or just left for the metadata info in title bar).
2024-08-19 23:01:55 -05:00
Gazook89
9adc3e2e1a linting 2024-08-19 22:49:38 -05:00
Gazook89
fd00a9f81d remove some console logs and some linting 2024-08-19 22:46:25 -05:00
Gazook89
720e43e9d9 update page increment/decrement buttons
putting the `pageInput - 1` modifier in the `scrollToPage` method allows for more understandable button function ('back button' is `- 1` and 'forward button' is `+ 1`).
2024-08-19 22:43:41 -05:00
Gazook89
176977dd2a change input type to 'text'
Changing input type to text removes the "spinner" controls from within the text box.  The spinner buttons are an accessibility issue (the tiny buttons are tiny), and we already have better buttons for incrementing/decrementing page number.

Text box only accepts numbers.
2024-08-19 22:40:50 -05:00
Gazook89
a42b867bcb create handler function for controlled input
Moved onChange handler function to a component method and simplified it a smidge.

Must use parseInt now because the input type will change to 'text' rather than 'number'
2024-08-19 22:38:46 -05:00
Gazook89
1196a1577f update minZoom and maxZoom variable names
Forgot to update the zoom variable names after making them all uppercase at their assignments.
2024-08-19 22:35:35 -05:00
Gazook89
54b11b1a4c refactor useEffect for updating currentPage state
The current page and the current page input share the same value, so the useEffect hook can be simplified.
2024-08-19 22:34:32 -05:00
Gazook89
7fa9b3cdd2 rearrange state declarations for pages
totalPages shouldn't need to be in state, since this component won't be changing it.

renamed pageNumberInput to just pageInput.  Was just something that happened in the course of working on it.

currentPage doesn't need to have it's own state separate from pageInput, they should always be the same *value*.
2024-08-19 22:32:02 -05:00
Gazook89
2f42c3f857 change top level constants to all caps
Better matches style of top level constants elsewhere in repo
2024-08-19 22:27:49 -05:00
David Bolack
67e868b5ee Rewrite path oncomponant load for cloned brews to prevent losing active changes on the "new" document. 2024-08-19 20:35:23 -05:00
David Bolack
3a81521e6f Work around users using Definition lists as paragraph indents. 2024-08-19 19:40:55 -05:00
David Bolack
a30608a8ae Promote : paragraph breaks shortcut to a token. 2024-08-19 10:36:26 -05:00
dependabot[bot]
6a129aebdb Bump @googleapis/drive from 8.11.0 to 8.11.1
Bumps [@googleapis/drive](https://github.com/googleapis/google-api-nodejs-client) from 8.11.0 to 8.11.1.
- [Release notes](https://github.com/googleapis/google-api-nodejs-client/releases)
- [Changelog](https://github.com/googleapis/google-api-nodejs-client/blob/main/release-please-config.json)
- [Commits](https://github.com/googleapis/google-api-nodejs-client/compare/drive-v8.11.0...drive-v8.11.1)

---
updated-dependencies:
- dependency-name: "@googleapis/drive"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-19 03:58:19 +00:00
David Bolack
184f182b3a Short term fix for the colons in codeblocks issue. 2024-08-18 21:52:29 -05:00
Gazook89
05dd5e4c04 Change .toolbar position to absolute
Set as relative position, the toolbar (and mysteriously, the pageInfo box) would jump up 29px (toolbar height) when the "next page" button was clicked.  absolute pos fixes this.
2024-08-18 18:51:46 -05:00
Gazook89
499c640a11 Move the Toolbar component out of the iframe
The website UI should stay out of the iframe if possible.  Otherwise, users can style the UI on their brew which may or may not be a pain, and it's simple enough to avoid it.
2024-08-18 18:50:36 -05:00
Gazook89
5a11b7918e refactor slider onChange and button onClick
Moved the zoomLevel state assignment to a newer useState hook function, making it easier (and shorter) to update that state within event handlers.

The slider onChange is a single easy line, and the buttons handlers are two lines for clarity.
2024-08-18 00:02:49 -05:00
Gazook89
36ab6923ed remove zoomInput state property
zoomLevel and zoomInput should always be the same, so I've removed one.
2024-08-17 23:43:32 -05:00
Gazook89
7cc967ad49 setZoomLevel to no longer use if/else
Remove the 'in'/'out' parameter of the function and just have the buttons send postive or negative integers equal to the desired change in the zoom.  No need for if/else statements using strings.
2024-08-17 23:39:59 -05:00
Gazook89
d108088295 remove unneeded handler 2024-08-17 21:23:12 -05:00
Gazook89
8be3154865 rename functions/attributes
updateZoom() => handleZoom

updateZoom prop => onZoomChange

More clarity of prop versus handler function.
2024-08-17 20:48:30 -05:00
Gazook89
9aa7c67c5b remove "makeZoom" function
The makeZoom function is redundant if we just insert the style a little further down when the `.pages` div is initialized, as a `style` attribute on the tag.
2024-08-17 20:41:59 -05:00
Gazook89
5a84c0aaa7 Merge branch 'pr/3499' into Simplify-Zoom-Slider 2024-08-17 20:22:57 -05:00
Gazook89
4a6418a475 fix padding on sides of slider
Extra padding on the sides of a range slider extends the length of the slider, such that you can't move the thumb all the way to the end.
2024-08-17 18:08:33 -05:00
Gazook89
efb4c67e2a use zoom icons rather than text 2024-08-17 15:40:52 -05:00
Gazook89
b325779466 remove extra line breaks 2024-08-17 15:38:27 -05:00
Gazook89
0d475ab035 refactor some properties
Mostly change some properties from things like "transparent" to "unset".  A lot of things that are just overriding the default Naturalcrit "colored button".  Moved some properties to the top level `.toolbar` class and let it cascade down.
2024-08-17 15:38:00 -05:00
Gazook89
c791c0f60b modify the interactive states
more closely match the properties editor behavior.  removed some unnecessary (unused) properties.  Outline only appears when element is focused (rather than on hover as well).
2024-08-17 15:36:12 -05:00
Gazook89
f204b0ebc0 tool elements use width:auto for flexibility, but with min-width
Set the child elements of the toolbar to have auto width (can expand as needed), but have a min-width so no button, such as an icon, is too small.
2024-08-17 15:34:13 -05:00
Gazook89
adab8449e0 Change toolbar spacing
replace column-/row-gap with a single gap at 5px.  Padding on each child element will provide the space.  Set a height on toolbar, so child elements can be set to 100% height to improve bg color change on hover.
2024-08-17 15:32:30 -05:00
Gazook89
fc96f6bf95 text input changes (text-transform, radius, border, focus)
Aligning input here with Properties editor inputs.  Removed border radius, added thin border, a focus border.
2024-08-17 14:45:50 -05:00
Gazook89
9924c6049e Aesthetic changes to tooltip (radius, bg color)
Matching tooltip color to the background of the input it belongs to, for better cohesion.  Removed border-radius as well.
2024-08-17 14:26:45 -05:00
Gazook89
21e9251043 aesthetic changes (border, text align, font size)
Text align isn't doing anything, and no other UI element is using a border and doesn't seem necessary here.  Maintains the "flat" design.
2024-08-17 14:25:04 -05:00
Gazook89
19e6d94419 Set as Relative position, remove extra properties
Doesn't need to be Sticky positioning, relative is fine (it is still fixed above the iframe).  Allows us to remove a bunch of extra properties.

Add a smidgen of padding.
2024-08-17 14:23:33 -05:00
Gazook89
232f28b5b4 Remove extra styling of the slider thumb
can just use browser defaults for this.
2024-08-17 14:06:58 -05:00
Gazook89
6af5abd37d Rearrange nesting of slider tooltip
Just moving the :hover:after tooltip to within the existing css rule for sliders.
2024-08-17 14:06:14 -05:00
Gazook89
e0e49c606f Utilize browser defined style for slider, with accent-color
Avoid over-styling of browser-defined slider, but still apply a HB appropriate color scheme.  Prevents us from having to create our own tick marks, so we can just define the `option`s in the datalist and get tick marks in the right spot.
2024-08-17 14:05:14 -05:00
Gazook89
e9e49e39fb Set preview zoom to update with onChange
Commented out the existing onChange handler, switched the onMouseUp that actually applies the zoom to onChange.
2024-08-17 13:59:58 -05:00
Gazook89
ee4eb19f1e Run ESLint auto lint (spaces to tabs mostly) 2024-08-17 13:57:50 -05:00
G.Ambatte
cc9edcc67c Prevent styling of lines inside folded sections 2024-08-17 23:11:04 +12:00
Víctor Losada Hernández
032fcf12e0 "Removed dynamic generation of zoom levels in datalist, replaced with a single static option of 100%" 2024-08-17 11:39:22 +02:00
G.Ambatte
174024b472 Merge branch 'master' into fixMaskSkewing-#3636 2024-08-17 11:02:25 +12:00
G.Ambatte
8a8cd3fb18 Change order of operations in mask img transform 2024-08-17 10:54:02 +12:00
G.Ambatte
dff0a7ae77 Merge branch 'addCSSRoute-#1097' of https://github.com/G-Ambatte/homebrewery into addCSSRoute-#1097 2024-08-17 10:27:09 +12:00
G.Ambatte
014482b3d5 Remove app.spec.js test command 2024-08-17 10:26:59 +12:00
G.Ambatte
ce7a98f974 Merge branch 'master' into addCSSRoute-#1097 2024-08-17 10:25:18 +12:00
Víctor Losada Hernández
5ee4ada112 "Updated ToolBar component: added zoom level limits, refactored zoom level handling, and modified CSS styles for input and slider elements." 2024-08-16 15:58:00 +02:00
G.Ambatte
de20311299 Fix package-lock.json 2024-08-16 22:01:37 +12:00
G.Ambatte
5fede97fa5 Merge branch 'master' into fixLinks-#3547 2024-08-16 21:46:37 +12:00
David Bolack
51f758bf47 Rework page counters for skipping and resets.
Solves #513

This adds the .skipCounting and .resetCounting classes for causing
a page number to not be incremented or to reset the number at 1.

The ToC Snippet is corrected to match the displayed page numbers
while correctly tracking the page ids.
2024-08-15 17:15:49 -05:00
Víctor Losada Hernández
f0765b5aaa "refactored ToolBar component to use a single state object, and updated styles in toolBar.less" 2024-08-15 20:05:23 +02:00
Víctor Losada Hernández
9dde4aa94e Merge branch 'pdf-tools' of https://github.com/5e-Cleric/homebrewery into pdf-tools 2024-08-15 17:46:49 +02:00
Víctor Losada Hernández
1452920fbd Merge branch 'master' of https://github.com/naturalcrit/homebrewery into pdf-tools 2024-08-15 17:41:27 +02:00
Víctor Losada Hernández
7b18c3ea0a Merge branch 'master' into metadata-api-endpoint 2024-08-15 17:35:51 +02:00
David Bolack
17b22b8afe Merge branch 'master' into Issue_241_Part_II 2024-08-15 09:41:03 -05:00
David Bolack
81a098b6cf Merge branch 'master' into Issue_241 2024-08-15 09:40:23 -05:00
Víctor Losada Hernández
cc76ff1478 relocated container query 2024-08-15 12:07:55 +02:00
Víctor Losada Hernández
c6f87eded0 add vault nav item to userpage 2024-08-14 20:42:18 +02:00
Víctor Losada Hernández
bbe56bf443 linting 2024-08-14 20:39:15 +02:00
Víctor Losada Hernández
f449132b4c wrap correctly 2024-08-14 20:38:38 +02:00
Víctor Losada Hernández
1c0bbc9390 linting 2024-08-14 20:05:28 +02:00
Víctor Losada Hernández
bf3c083e8c flow changed, flex added, elipsis added 2024-08-14 16:33:02 +02:00
Víctor Losada Hernández
031ed751d1 up less js 2024-08-14 16:30:33 +02:00
David Bolack
aa2fe3ef97 Merge branch 'master' into FalsePaths 2024-08-13 22:12:03 -05:00
Trevor Buckner
31fcf28e3f Merge pull request #3631 from naturalcrit/v3.14.1
Up to v3.14.1
2024-08-13 17:11:08 -04:00
Trevor Buckner
aa945c4177 Up to v3.14.1 2024-08-13 17:08:59 -04:00
David Bolack
52faa366ca Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-08-13 12:30:16 -05:00
David Bolack
2d781f02e3 Merge branch 'master' into Issue_241_Part_II 2024-08-13 12:26:29 -05:00
David Bolack
baf201cc3a Merge branch 'master' into Issue_1958 2024-08-13 12:25:49 -05:00
David Bolack
fc6930c868 Merge branch 'master' into Issue_241 2024-08-13 12:17:45 -05:00
David Bolack
1ed7e43db1 Implement G-Ambette's cleaner fix. 2024-08-13 12:09:45 -05:00
David Bolack
6ec51bf725 Revert "Prevent loading of undefined renderer or theme themebundle."
This reverts commit 136e877ee6.
2024-08-13 12:09:26 -05:00
G.Ambatte
ae336f1429 Add extra getCSS tests 2024-08-13 22:30:59 +12:00
G.Ambatte
5847b246ef Add getCSS test 2024-08-13 22:05:03 +12:00
G.Ambatte
38168131e7 Remove app.spec.js 2024-08-13 22:03:06 +12:00
G.Ambatte
00e113ff67 Move getCSS to homebrew.api.js 2024-08-13 22:02:54 +12:00
Víctor Losada Hernández
62b96f4e79 change back prop names 2024-08-13 12:00:58 +02:00
David Bolack
136e877ee6 Prevent loading of undefined renderer or theme themebundle. 2024-08-12 21:42:25 -05:00
Víctor Losada Hernández
8faae1e645 Remove console log statement for invalid search in VaultPage component. 2024-08-13 00:51:28 +02:00
Víctor Losada Hernández
e4852b7077 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-08-13 00:47:25 +02:00
G.Ambatte
2ba42def09 Merge branch 'master' into addCSSRoute-#1097 2024-08-12 22:01:56 +12:00
G.Ambatte
337d3567fc Merge branch 'addCSSRoute-#1097' of https://github.com/G-Ambatte/homebrewery into addCSSRoute-#1097 2024-08-12 18:49:11 +12:00
G.Ambatte
3dc8eec1e6 Add app test NPM command 2024-08-12 18:49:01 +12:00
G.Ambatte
fac2293b77 Add App test file 2024-08-12 18:48:46 +12:00
G.Ambatte
7d699e455e Switch CSS route to call a function 2024-08-12 18:48:28 +12:00
Trevor Buckner
cbc6dcdc35 Merge pull request #3625 from G-Ambatte/fixVarNameAsParam-#3622
Tweak variable math split regex
2024-08-11 23:01:38 -04:00
Trevor Buckner
5894dc5a7a Merge branch 'master' into fixVarNameAsParam-#3622 2024-08-11 21:59:58 -04:00
Trevor Buckner
284bfe565b Merge pull request #3624 from G-Ambatte/fixVarNameSubstringClash-#3613
Fix var name substring clash #3613
2024-08-11 21:49:31 -04:00
G.Ambatte
e03b540788 Merge branch 'master' into addCSSRoute-#1097 2024-08-10 18:03:50 +12:00
Víctor Losada Hernández
2dc4ebb39f Remove console log and CSS rule for hr element in vaultPage. 2024-08-10 00:12:17 +02:00
Víctor Losada Hernández
59672b79d8 remove unnecessary changes in unrelated files 2024-08-10 00:05:58 +02:00
Víctor Losada Hernández
59717fe630 "Refactor VaultPage component, update styles, and modify server-side API queries" 2024-08-10 00:00:43 +02:00
Víctor Losada Hernández
3f9c7a1794 "Moved and rearranged conditional statements for rendering no search/brews found messages in VaultPage component." 2024-08-09 23:15:59 +02:00
Víctor Losada Hernández
ca1f2dd1c3 fix validity check 2024-08-09 22:57:17 +02:00
Víctor Losada Hernández
a8e6f5cf26 "Refactor VaultPage component: moved form validation logic, removed unnecessary variables, and rearranged code structure." 2024-08-09 22:53:20 +02:00
Víctor Losada Hernández
f3a774d55c "Removed unnecessary conditional statement in buildBrewsQuery function" 2024-08-09 22:46:25 +02:00
Víctor Losada Hernández
834980890a "Refactor VaultPage component: update form validation and submission logic" 2024-08-09 22:44:26 +02:00
Víctor Losada Hernández
969eb354ce include query example for future debugging 2024-08-09 22:35:39 +02:00
G.Ambatte
075c8805e0 Merge branch 'fixVarNameAsParam-#3622' of https://github.com/G-Ambatte/homebrewery into fixVarNameAsParam-#3622 2024-08-10 08:24:23 +12:00
G.Ambatte
5c4187cd06 Add variable names as function parameter tests 2024-08-10 08:24:16 +12:00
G.Ambatte
1719cc68fa Merge branch 'master' into fixVarNameAsParam-#3622 2024-08-10 08:23:23 +12:00
G.Ambatte
3ba67fb3d0 Merge branch 'master' into fixVarNameSubstringClash-#3613 2024-08-10 07:56:04 +12:00
G.Ambatte
f58d52c4b6 Add comma to var math split regex 2024-08-10 07:54:50 +12:00
Víctor Losada Hernández
9288ead130 remove owner functionality completely 2024-08-09 19:24:39 +02:00
Víctor Losada Hernández
a8a4930225 Merge branch 'experimental-development' of https://github.com/5e-Cleric/homebrewery; branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-08-09 18:54:51 +02:00
Trevor Buckner
e1ad6f8114 Merge pull request #3588 from G-Ambatte/fixInfoPanel-#3586
Add disableMeta prop to SharePage
2024-08-09 10:55:27 -04:00
G.Ambatte
22257a95e0 Merge branch 'master' into fixInfoPanel-#3586 2024-08-09 18:06:07 +12:00
G.Ambatte
713c978f08 Add disableMeta to /migrate 2024-08-09 18:05:36 +12:00
G.Ambatte
3eb0c7acfe Add variable name checks 2024-08-09 17:42:15 +12:00
G.Ambatte
c3e6c01ec1 Fix typo in regex 2024-08-09 15:33:28 +12:00
G.Ambatte
190bce519f Merge branch 'master' into addCSSRoute-#1097 2024-08-09 15:29:56 +12:00
G.Ambatte
5bb5cdec05 Change replaceAll to use RegEx from string 2024-08-09 13:10:30 +12:00
Trevor Buckner
f8e68c1485 Merge pull request #3620 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-jest-28.8.0
Bump eslint-plugin-jest from 28.7.0 to 28.8.0
2024-08-08 18:14:24 -04:00
Trevor Buckner
60ccd08bce Merge branch 'master' into dependabot/npm_and_yarn/eslint-plugin-jest-28.8.0 2024-08-08 17:53:01 -04:00
Trevor Buckner
f241024167 Merge pull request #3585 from dbolack-ab/CSSFolding
Add Code folding on CSS style tab
2024-08-08 17:51:43 -04:00
Trevor Buckner
f1fd75574d Merge branch 'master' into CSSFolding 2024-08-08 17:51:05 -04:00
Trevor Buckner
31352e417f Simplify folding logic 2024-08-08 17:48:32 -04:00
Trevor Buckner
643af98ca3 Add comment 2024-08-08 17:44:16 -04:00
Trevor Buckner
3b61cd355f Fix edge case where string was emitting data: twice.
Also, a case where the input is right around 50 chars. It can be truncated twice, leading to a long `.....`
2024-08-08 17:43:57 -04:00
Trevor Buckner
8df19e3b8f Merge branch 'master' into dependabot/npm_and_yarn/eslint-plugin-jest-28.8.0 2024-08-08 11:14:13 -04:00
Trevor Buckner
91d6548822 Merge pull request #3621 from naturalcrit/dependabot/npm_and_yarn/marked-emoji-1.4.2
Bump marked-emoji from 1.4.1 to 1.4.2
2024-08-08 11:13:55 -04:00
dependabot[bot]
ef797b2a69 Bump marked-emoji from 1.4.1 to 1.4.2
Bumps [marked-emoji](https://github.com/UziTech/marked-emoji) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/UziTech/marked-emoji/releases)
- [Changelog](https://github.com/UziTech/marked-emoji/blob/main/release.config.cjs)
- [Commits](https://github.com/UziTech/marked-emoji/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: marked-emoji
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-08 03:05:41 +00:00
dependabot[bot]
33a62a0ac7 Bump eslint-plugin-jest from 28.7.0 to 28.8.0
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 28.7.0 to 28.8.0.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.7.0...v28.8.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-08 03:05:17 +00:00
Trevor Buckner
5a9025f555 Merge pull request #3618 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-jest-28.7.0
Bump eslint-plugin-jest from 28.6.0 to 28.7.0
2024-08-07 13:15:48 -04:00
Trevor Buckner
0a494633bb Merge branch 'master' into dependabot/npm_and_yarn/eslint-plugin-jest-28.7.0 2024-08-07 12:00:40 -04:00
Trevor Buckner
aeaea5b5e0 Merge pull request #3516 from dbolack-ab/Issue_2563
Update table of content list-item breakage rules for wide table of contents
2024-08-07 12:00:23 -04:00
Trevor Buckner
e03ec34104 Merge branch 'master' into Issue_2563 2024-08-07 11:59:32 -04:00
dependabot[bot]
c65ee59998 Bump eslint-plugin-jest from 28.6.0 to 28.7.0
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 28.6.0 to 28.7.0.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.6.0...v28.7.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-05 03:15:14 +00:00
Trevor Buckner
4d59a14f74 Merge pull request #3617 from naturalcrit/lint-metadataEditor.less
Lint metadataEditor.less
2024-08-03 17:29:47 -04:00
Trevor Buckner
3c8aaa7465 Update metadataEditor.less 2024-08-03 17:28:47 -04:00
Trevor Buckner
ac70403203 Merge pull request #3611 from naturalcrit/dependabot/npm_and_yarn/react-router-dom-6.26.0
Bump react-router-dom from 6.25.1 to 6.26.0
2024-08-03 02:51:13 -04:00
dependabot[bot]
a5e7ad882d Bump react-router-dom from 6.25.1 to 6.26.0
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.25.1 to 6.26.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.26.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-03 06:47:06 +00:00
Trevor Buckner
061925e89a Merge pull request #3616 from naturalcrit/Replace-stylistic-stylelint-with-@stylistic-stylelint
Migrate from stylelint-stylistic to @stylelint-stylistic
2024-08-03 02:46:04 -04:00
Trevor Buckner
5fc8b508d1 Merge branch 'master' into Replace-stylistic-stylelint-with-@stylistic-stylelint 2024-08-03 02:43:33 -04:00
Trevor Buckner
cb444bef9d stylelint-stylistic has a new owner; migrating to newer package 2024-08-03 02:42:22 -04:00
Trevor Buckner
481f2e7d39 Merge pull request #3587 from G-Ambatte/addSignedFunction-#3537
Add new var math functions
2024-08-03 02:12:23 -04:00
Trevor Buckner
7559652a32 Merge branch 'master' into addSignedFunction-#3537 2024-08-03 02:09:47 -04:00
Trevor Buckner
8e15466063 Merge pull request #3615 from G-Ambatte/fixSelectSelfInThemeSource-#3614
Prevent self-selection of User Theme
2024-08-03 02:07:33 -04:00
G.Ambatte
8ef319d2cd Merge branch 'master' into fixSelectSelfInThemeSource-#3614 2024-08-03 16:35:17 +12:00
G.Ambatte
1513a983f7 Skip self when generating metadata dropdown list 2024-08-03 16:32:49 +12:00
G.Ambatte
b99c0382f6 Merge branch 'master' into fixLinks-#3547 2024-08-03 14:13:42 +12:00
G.Ambatte
1b71bbaefb Remove escaping from new functions 2024-08-03 10:32:39 +12:00
G.Ambatte
fcd5279381 Enable built-in abs() 2024-08-03 10:32:18 +12:00
G.Ambatte
4276d38152 Merge branch 'master' into addSignedFunction-#3537 2024-08-03 09:47:00 +12:00
David Bolack
0057e2b57e Merge branch 'master' into Issue_241_Part_II 2024-08-02 15:53:03 -05:00
David Bolack
6f4604c8a9 Merge branch 'master' into Issue_241 2024-08-02 15:51:53 -05:00
David Bolack
13fa06ec1f Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-08-02 15:49:34 -05:00
David Bolack
e2ce1185b6 Merge branch 'master' into Issue_1958 2024-08-02 15:47:50 -05:00
David Bolack
d6bf2dec7e Merge branch 'master' into CSSFolding 2024-08-02 15:27:04 -05:00
David Bolack
423a4a521a Correct truncation when looking for data: in css folding 2024-08-02 15:25:41 -05:00
David Bolack
05d4d5b1ff Revert "Correct truncation when looking for data: in css folding"
This reverts commit ad1e8d50d7.
2024-08-02 15:25:10 -05:00
David Bolack
ad1e8d50d7 Correct truncation when looking for data: in css folding 2024-08-02 15:24:14 -05:00
David Bolack
c926f0de79 Resolve import matching suggestion. 2024-08-02 15:10:39 -05:00
Trevor Buckner
8983d74775 rebuild package lock again? 2024-08-01 21:30:09 -04:00
Trevor Buckner
f084c11936 Update package-lock.json 2024-08-01 21:26:04 -04:00
Víctor Losada Hernández
fa0d1d6bc1 Merge branch 'master' into metadata-api-endpoint 2024-08-01 23:44:00 +02:00
Trevor Buckner
a442817226 Re-build package-lock. 2024-08-01 17:43:54 -04:00
Víctor Losada Hernández
4337c67f69 Merge branch 'master' into Issue_2563 2024-08-01 23:37:43 +02:00
Trevor Buckner
bb06a3e4d4 Merge pull request #3526 from 5e-Cleric/fix-background-monster-in-safari
Fixing Monster Frame background in Safari for iphone and ipad
2024-08-01 17:23:37 -04:00
Trevor Buckner
6af9c9e432 Merge branch 'master' into Issue_2563 2024-08-01 17:16:18 -04:00
Trevor Buckner
84d0d15c5a Merge branch 'master' into fix-background-monster-in-safari 2024-08-01 17:07:18 -04:00
Trevor Buckner
b185fe8e35 Move Monster block changes under main monster block stuff 2024-08-01 17:06:18 -04:00
Trevor Buckner
adbb9e54c1 Merge branch 'master' into addSignedFunction-#3537 2024-08-01 16:12:46 -04:00
Trevor Buckner
1d3c2d7cd6 Merge branch 'master' into fixInfoPanel-#3586 2024-08-01 15:57:43 -04:00
Trevor Buckner
2dc397e9f1 Merge pull request #3610 from naturalcrit/MoveMigrateToSharePage
Move Migrate page to use Share component
2024-08-01 15:56:37 -04:00
Trevor Buckner
6465564b6f Add route to Homebrew.jsx 2024-08-01 15:37:00 -04:00
G.Ambatte
e1fe640e92 Update shared/naturalcrit/markdown.js
Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
2024-08-02 07:03:27 +12:00
G.Ambatte
6f99fe7455 Update shared/naturalcrit/markdown.js
Co-authored-by: Trevor Buckner <calculuschild@gmail.com>
2024-08-02 07:02:57 +12:00
Trevor Buckner
4b3b44ecc8 Merge branch 'master' into addCSSRoute-#1097 2024-08-01 14:28:10 -04:00
David Bolack
73e579703a Merge branch 'master' into Issue_1958 2024-08-01 11:19:17 -05:00
David Bolack
129e18da0f Merge branch 'master' into Issue_241 2024-08-01 11:04:52 -05:00
David Bolack
f10ef2bdb3 Merge branch 'master' into Issue_241_Part_II 2024-08-01 11:02:30 -05:00
Víctor Losada Hernández
2bc7cda8c9 fixes 2024-08-01 17:36:14 +02:00
David Bolack
342963dae6 Merge branch 'master' into Issue_2563 2024-08-01 10:33:34 -05:00
David Bolack
957b1ed9e7 Merge branch 'master' into CSSFolding 2024-08-01 10:09:56 -05:00
David Bolack
31b3bd1ace Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-08-01 09:25:30 -05:00
Víctor Losada Hernández
f1ab332ce0 hide instead of comment 2024-08-01 16:02:00 +02:00
Víctor Losada Hernández
d50f23354a minor changes 2024-08-01 15:57:27 +02:00
Víctor Losada Hernández
662a2d776a Merge branch 'experimental-development' of https://github.com/5e-Cleric/homebrewery into experimental-development 2024-08-01 15:55:09 +02:00
Víctor Losada Hernández
80f07bf0b0 Nav item 2024-08-01 15:55:04 +02:00
Víctor Losada Hernández
6cf2dd8186 Merge branch 'master' into experimental-development 2024-08-01 15:49:52 +02:00
Víctor Losada Hernández
5de20cb451 disabling owner input 2024-08-01 15:32:13 +02:00
Trevor Buckner
423ed28fbd Merge pull request #3517 from dbolack-ab/Issue_2688
Solve for .descriptive and .wide not getting along
2024-08-01 00:59:03 -04:00
Trevor Buckner
a4f17259e1 Merge branch 'master' into Issue_2688 2024-08-01 00:58:06 -04:00
Trevor Buckner
c2678e5f2c Merge pull request #3564 from G-Ambatte/fixInkFriendlySnippet-#3563
Stop Ink Friendly snippet making text unselectable in output PDF
2024-08-01 00:48:21 -04:00
Trevor Buckner
d797333b97 Merge branch 'master' into fixInkFriendlySnippet-#3563 2024-08-01 00:48:14 -04:00
Trevor Buckner
40777a3794 Merge pull request #3580 from G-Ambatte/fixToCUpperCasing-#3572
Fix Table of Contents uppercasing
2024-08-01 00:47:23 -04:00
Trevor Buckner
ac1005c2b0 Merge branch 'master' into fixInkFriendlySnippet-#3563 2024-08-01 00:47:02 -04:00
Trevor Buckner
c77395149b Tweak shadow values to match 5ePHB
box-shadows are a little smaller than drop-shadow. This just uses the same values we already found previously so the shadow size is not affected.
2024-08-01 00:46:08 -04:00
Trevor Buckner
fb0580fff1 Merge branch 'master' into fixToCUpperCasing-#3572 2024-08-01 00:41:47 -04:00
Trevor Buckner
0e953d08b2 Merge pull request #3609 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.25.3
Bump @babel/preset-env from 7.25.2 to 7.25.3
2024-07-31 23:54:21 -04:00
dependabot[bot]
7fce362a52 Bump @babel/preset-env from 7.25.2 to 7.25.3
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.25.2 to 7.25.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.3/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 03:47:39 +00:00
Trevor Buckner
3e7844ba6d Merge pull request #3591 from naturalcrit/dependabot/npm_and_yarn/eslint-plugin-react-7.35.0
Bump eslint-plugin-react from 7.34.3 to 7.35.0
2024-07-31 23:45:53 -04:00
Trevor Buckner
7619f8f420 Merge branch 'master' into dependabot/npm_and_yarn/eslint-plugin-react-7.35.0 2024-07-31 22:43:52 -04:00
Trevor Buckner
bac52f8376 Merge pull request #3582 from naturalcrit/dependabot/npm_and_yarn/react-router-dom-6.25.1
Bump react-router-dom from 6.24.1 to 6.25.1
2024-07-31 22:43:39 -04:00
Trevor Buckner
5c72cd9d47 Merge branch 'master' into dependabot/npm_and_yarn/react-router-dom-6.25.1 2024-07-31 21:54:53 -04:00
Trevor Buckner
89b59a52bc Merge pull request #3608 from G-Ambatte/fixTests
Fix tests post v3.14.0
2024-07-31 21:54:32 -04:00
Trevor Buckner
a6f2a1a4c8 Merge branch 'master' into fixTests 2024-07-31 21:51:46 -04:00
Trevor Buckner
e9e9fbe21c Merge pull request #3592 from dbolack-ab/UpdateDocker
Update Node version for Docker
2024-07-31 21:51:16 -04:00
G.Ambatte
e7108947d6 Fix expected values for pageCount and renderer 2024-08-01 13:24:23 +12:00
G.Ambatte
8b68f24135 Merge branch 'master' into fixInkFriendlySnippet-#3563 2024-08-01 12:43:20 +12:00
G.Ambatte
e32ae9a792 Merge branch 'master' into fixToCUpperCasing-#3572 2024-08-01 12:42:08 +12:00
G.Ambatte
758a951bf5 Merge branch 'master' into fixInfoPanel-#3586 2024-08-01 12:33:07 +12:00
G.Ambatte
21ac50cd27 Merge branch 'master' into addSignedFunction-#3537 2024-08-01 12:32:07 +12:00
dependabot[bot]
fc67a40167 Bump eslint-plugin-react from 7.34.3 to 7.35.0
Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.34.3 to 7.35.0.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.3...v7.35.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-31 23:35:07 +00:00
dependabot[bot]
7949df1865 Bump react-router-dom from 6.24.1 to 6.25.1
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.24.1 to 6.25.1.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.25.1/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-31 23:35:06 +00:00
Trevor Buckner
8ed013cbb2 Merge pull request #3603 from naturalcrit/dependabot/npm_and_yarn/mongoose-8.5.2
Bump mongoose from 8.4.5 to 8.5.2
2024-07-31 19:34:29 -04:00
Trevor Buckner
0138c27863 Merge branch 'master' into dependabot/npm_and_yarn/mongoose-8.5.2 2024-07-31 19:34:00 -04:00
Trevor Buckner
7930c209ff Merge pull request #3599 from naturalcrit/dependabot/npm_and_yarn/babel/preset-env-7.25.2
Bump @babel/preset-env from 7.24.7 to 7.25.2
2024-07-31 19:33:51 -04:00
dependabot[bot]
26fdc1ba91 Bump mongoose from 8.4.5 to 8.5.2
Bumps [mongoose](https://github.com/Automattic/mongoose) from 8.4.5 to 8.5.2.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/8.4.5...8.5.2)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-31 23:33:27 +00:00
Trevor Buckner
8681994747 Merge branch 'master' into dependabot/npm_and_yarn/babel/preset-env-7.25.2 2024-07-31 19:32:52 -04:00
Trevor Buckner
0e684b14a7 Merge pull request #3598 from naturalcrit/dependabot/npm_and_yarn/babel/core-7.25.2
Bump @babel/core from 7.24.7 to 7.25.2
2024-07-31 19:32:44 -04:00
Trevor Buckner
974f84d49f Merge branch 'master' into dependabot/npm_and_yarn/babel/core-7.25.2 2024-07-31 19:32:28 -04:00
Trevor Buckner
5a6abef4fb Merge pull request #3562 from naturalcrit/dependabot/npm_and_yarn/dompurify-3.1.6
Bump dompurify from 3.1.5 to 3.1.6
2024-07-31 19:32:09 -04:00
Trevor Buckner
15200e0c6e Merge branch 'master' into dependabot/npm_and_yarn/dompurify-3.1.6 2024-07-31 19:31:25 -04:00
Trevor Buckner
79c22f383f Allow renderer and pagecount into stubs
At this point, only text and textbin contents are still in google drive. Which is the majority of the file still. Renderer and Pagecount may become useful for Vault page, and Renderer is needed for themes.
2024-07-31 18:13:31 -04:00
Trevor Buckner
915f9aafa8 restore snippetBundle field somehow lost from /new and /home 2024-07-31 17:27:58 -04:00
Víctor Losada Hernández
aa0d0bed48 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-07-31 23:12:47 +02:00
Trevor Buckner
11f8809c5e Merge pull request #3606 from naturalcrit/FixUserThemesCrashes
Fix user themes crashes
2024-07-31 17:05:52 -04:00
Trevor Buckner
27a4831ea0 Add a theme to our reference pages (changelog, FAQ, migrate) 2024-07-31 16:53:54 -04:00
Trevor Buckner
1abced20d6 Do not fetch user themes if there is no user. 2024-07-31 16:53:34 -04:00
G.Ambatte
e3586f0734 Fix errors introduced during merge conflict resolution 2024-07-31 22:17:31 +12:00
G.Ambatte
8d49422061 Link clean up 2024-07-31 21:43:49 +12:00
G.Ambatte
59790bd005 Merge branch 'master' into fixLinks-#3547 2024-07-31 21:42:42 +12:00
G.Ambatte
251d03b7be Merge branch 'master' into addSignedFunction-#3537 2024-07-31 20:58:40 +12:00
Víctor Losada Hernández
c92f30cfe0 change owner default to false 2024-07-31 08:58:23 +02:00
Víctor Losada Hernández
2a8e4b2a63 Merge branch 'experimental-development' of https://github.com/5e-Cleric/homebrewery into experimental-development 2024-07-31 08:57:42 +02:00
Víctor Losada Hernández
51c7549b45 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-07-31 08:57:28 +02:00
Víctor Losada Hernández
ea5170e6a6 Merge branch 'master' into experimental-development 2024-07-30 22:46:44 +02:00
David Bolack
29bbf3fef9 Merge branch 'master' into Issue_2563 2024-07-30 10:59:43 -05:00
David Bolack
a7f8b52966 Change default value for pageNumber on markdopwn.render() 2024-07-30 08:56:06 -05:00
David Bolack
6629bc64d8 Merge branch 'Issue_1430_Unique_HeaderIDs' of github.com:dbolack-ab/homebrewery into Issue_1430_Unique_HeaderIDs 2024-07-30 08:36:47 -05:00
David Bolack
bfd46fb6fd Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-07-30 08:35:12 -05:00
David Bolack
b34027699f Move livescrollToggle function out into a class method instead of an anonymous function.
Adjust code accordingly ( event.target vs document.getElementByClassname )
2024-07-30 03:09:25 -05:00
David Bolack
dcdc8b4943 Remove Livescrolling toggle hot-key. 2024-07-30 02:41:03 -05:00
David Bolack
184462616f Merge branch 'master' into Issue_241_Part_II 2024-07-30 02:31:14 -05:00
David Bolack
2d335ef7fc Merge branch 'master' into Issue_241 2024-07-30 02:30:57 -05:00
dependabot[bot]
fac0d151b6 Bump @babel/preset-env from 7.24.7 to 7.25.2
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.24.7 to 7.25.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.2/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-30 03:27:30 +00:00
dependabot[bot]
4f950b6024 Bump @babel/core from 7.24.7 to 7.25.2
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.24.7 to 7.25.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.25.2/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-30 03:27:04 +00:00
Trevor Buckner
1c1d331df9 Merge pull request #3597 from naturalcrit/v3.14.0
Up to v3.14.0
2024-07-29 21:55:19 -04:00
Trevor Buckner
8609925da8 Merge branch 'master' into v3.14.0 2024-07-29 21:54:38 -04:00
Trevor Buckner
607244d6e1 Merge pull request #3321 from dbolack-ab/brew_themes_user_selection
Enable User Brew theme selection
2024-07-29 21:54:28 -04:00
Trevor Buckner
9cc81d2ff9 Up to v3.14.0 2024-07-29 21:52:09 -04:00
Trevor Buckner
32fa50d608 Fallback to showing "Blank" theme if themes fail to load. 2024-07-29 12:30:13 -04:00
Trevor Buckner
8221579b6a Linting 2024-07-28 18:03:25 -04:00
Trevor Buckner
88eaebfd49 Raise test coverage threshold
This PR adds tests which means we are now covering a larger % of the codebase. Raise the coverage thresholds to match.
2024-07-28 18:00:33 -04:00
Trevor Buckner
ee9f2c8c83 Remove unused CSS endpoints in favor of #3075
Now that we have a dedicated /theme/ route for the recursive theming, the CSS endpoint can be simpler for only getting the `style` of a single brew. #3075 already has this simpler version, but no testing, so I have copied this into a comment there for implementation when it is ready.
2024-07-28 17:53:25 -04:00
Trevor Buckner
2870caaae6 Clean up metadataEditor theme dropdown 2024-07-28 17:18:30 -04:00
Trevor Buckner
e0425ec6c0 Simplify API call url 2024-07-28 16:47:16 -04:00
Trevor Buckner
8aa88a2e45 Add proper error popup when theme fails to load 2024-07-28 16:45:01 -04:00
Víctor Losada Hernández
cef90f5ff9 Added !brewCollection condition to if statement in VaultPage component. 2024-07-28 11:18:26 +02:00
Víctor Losada Hernández
5a9b77190a "Removed console log statement in VaultPage.jsx and updated brewsQuery logic in vault.api.js to handle legacy and v3 filters" 2024-07-28 11:10:27 +02:00
Víctor Losada Hernández
59a5f641af search by author 2024-07-28 10:45:56 +02:00
Trevor Buckner
edec9369ec Finish adding test cases 2024-07-27 19:17:19 -04:00
Trevor Buckner
f2d933410e Add error handling for missing themes 2024-07-27 19:17:05 -04:00
Víctor Losada Hernández
0bda666127 "Changed condition in onKeyDown event handler from checking input validity and value to checking searchButtonRef.current.disabled" 2024-07-27 10:46:08 +02:00
Víctor Losada Hernández
5b96ef4406 "Refactor VaultPage component: updated validateInput to validateForm, changed input validation logic, and added refs for search button and checkboxes." 2024-07-27 10:41:10 +02:00
Víctor Losada Hernández
af5bbdc677 change from $or to $in 2024-07-27 10:39:06 +02:00
Trevor Buckner
b64a0c5200 Start adding tests for /theme/ endpoint 2024-07-27 03:30:51 -04:00
Trevor Buckner
113f9b3fe3 No need to stringify Theme Bundle object 2024-07-27 02:00:38 -04:00
Víctor Losada Hernández
2c4f4ff5fc Merge branch 'master' into pdf-tools 2024-07-26 14:14:57 +02:00
Víctor Losada Hernández
c1dc712542 better checkboxes and linting 2024-07-25 23:48:37 +02:00
Víctor Losada Hernández
3e2c2de269 Added hideMoveArrows prop to split pane for use in vault 2024-07-25 23:11:51 +02:00
Víctor Losada Hernández
cc08579583 change to splitPane component 2024-07-25 16:57:33 +02:00
David Bolack
d2afa7adea Move fetchThemeBundle into /shared/helpers
This might not be the best rework - I was unsure if the *this* that would be available when called would see the appropriate object so I assumed not and pass it as a parameter.
Works, but may be bad form.
2024-07-23 22:17:52 -05:00
Víctor Losada Hernández
e562ebef48 media query for mobile use expanded to vertical stack 2024-07-24 00:50:21 +02:00
Víctor Losada Hernández
e206b501a6 media query to show only one column in case of small window 2024-07-24 00:34:13 +02:00
Víctor Losada Hernández
016a9fa1e8 few css changes to make the page more responsive on smaller screens 2024-07-24 00:26:23 +02:00
Víctor Losada Hernández
01ee184044 "Update default count value from 10 to 20 in VaultPage component and vault API" 2024-07-23 23:57:05 +02:00
Trevor Buckner
8e7baca47d Fix tests 2024-07-23 17:40:32 -04:00
Trevor Buckner
ddc5693778 revert package-lock 2024-07-23 17:31:07 -04:00
Trevor Buckner
82f73fb21d cleanup 2024-07-23 17:24:50 -04:00
Trevor Buckner
27c52fc244 Fix loading CSS for Legacy 2024-07-23 17:11:48 -04:00
Trevor Buckner
ac82e3ecb2 Add to home page 2024-07-23 16:50:29 -04:00
Trevor Buckner
22b6aa14f0 Add to /new page 2024-07-23 16:43:23 -04:00
Trevor Buckner
24ab3d3392 Merge branch 'brew_themes_user_selection' of https://github.com/dbolack-ab/homebrewery into pr/3321 2024-07-23 16:26:35 -04:00
Trevor Buckner
0b01f27d11 Load theme bundles on /share page 2024-07-23 16:26:33 -04:00
David Bolack
d640ad6bb7 Update Node version for Docker 2024-07-22 19:13:38 -05:00
Víctor Losada Hernández
fd91bf0fff Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-07-22 23:07:06 +02:00
Víctor Losada Hernández
270aa9e0f9 Merge branch 'master' into brew_themes_user_selection 2024-07-22 22:46:12 +02:00
Víctor Losada Hernández
24c950227a Merge branch 'master' into scroll-to-element 2024-07-22 22:43:43 +02:00
Trevor Buckner
6ae249a527 Lint 2024-07-22 02:46:26 -04:00
Trevor Buckner
c0123b96eb Support snippet compilation
Original handling of snippets only worked if the current selected theme was a staticTheme. This now fully merges all snippets through the theme chain no matter what the top-level theme is. So user themes built on 5ePHB can benefit from 5ePHB snippets too.

User input of user snippets will be a later PR, but merging them into static snippets is now supported.
2024-07-22 02:44:41 -04:00
Trevor Buckner
45f7080afd Move loadAllBrewStylesAndSnippets to the parent page component
Themes contain both CSS and Snippets. The brewRenderer only cares about the CSS, but other components need the Snippets. Better to have the parent "editPage", etc. load the theme bundles and pass them down to each child that needs it, rather than trying to pass from the child up.

This also fixes the `metadataEditor.jsx` not being able to change themes live; A new theme bundle is now loaded when a new theme is selected, instead of only the first time the BrewRenderer mounts.

Also renamed to "fetchThemeBundle"
2024-07-21 16:25:24 -04:00
David Bolack
2af2ad629d Try to account for situations where the URL folding is past the max length for the truncation so the user can see why this is a fold.
Remove missed debug messages.
2024-07-21 12:58:21 -05:00
David Bolack
2fc7aa454f Add data: URL folding for CSS.
Regex might need tweaking to catch all cases, but it catches the basics.
2024-07-21 12:40:49 -05:00
Víctor Losada Hernández
ddf2006285 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-07-21 18:06:08 +02:00
David Bolack
fde797c044 Rename prevLine to activeLine for better reading clarity. 2024-07-20 21:51:03 -05:00
David Bolack
6693fb1c13 reduce redundant trim()s 2024-07-20 21:40:22 -05:00
G.Ambatte
17f8de48a8 Add disableMeta prop to SharePage 2024-07-21 13:33:23 +12:00
Trevor Buckner
0a5ff213de use same theme endpoint for user and static themes
`getThemeBundle()` rework no longer needs two separate endpoints
2024-07-20 11:39:23 -04:00
G.Ambatte
aebfcc7885 Add new var math functions 2024-07-21 00:18:06 +12:00
David Bolack
2c4f3473e5 Trim the trailing { on a CSS fold. 2024-07-20 00:43:02 -05:00
G.Ambatte
9a4cc5f63e Add @import folding 2024-07-20 14:57:09 +12:00
David Bolack
c82b62f953 Add Code folding on CSS style tab 2024-07-19 16:03:44 -05:00
Víctor Losada Hernández
df265ffc8a Merge branch 'master' of https://github.com/naturalcrit/homebrewery into metadata-api-endpoint 2024-07-19 08:59:04 +02:00
Víctor Losada Hernández
73a400b882 Merge branch 'metadata-api-endpoint' of https://github.com/naturalcrit/homebrewery into metadata-api-endpoint 2024-07-19 08:58:21 +02:00
Víctor Losada Hernández
bcef4006dc Remove console.log statement in /metadata/:id route handler 2024-07-19 08:58:19 +02:00
Trevor Buckner
f364f054f8 restore renderStyle
`renderStyle` is still necessary; it allows us to update the style live in the component render step as the user types into the style tab. Otherwise the style is only rendered once and never updates.

React also discourages directly editing the DOM ourselves, because it makes changes to the DOM that react cannot track; we should aim to provide all DOM writes inside of the component render function instead of using `document.createElement`, etc.

Too that end, this commit reduces the `loadAllStylesAndSnippets` function to just fetch and parse the data; actual rendering is moved back to `renderStyle()`
2024-07-19 01:33:56 -04:00
Trevor Buckner
460358ce1f Simplify some logic 2024-07-19 00:09:21 -04:00
Trevor Buckner
0448f15322 Classify user brews as V3 if they use V3
Each theme in the theme chain, including user brews, must use the same renderer. When moving to V4 or future versions, it will be important to distinguish which themes are compatible with each other
2024-07-19 00:05:45 -04:00
Trevor Buckner
d741878f78 Also remove userthemes from Brew object in sharePage 2024-07-19 00:00:06 -04:00
G.Ambatte
b55db94822 Merge branch 'master' into fixLinks-#3547 2024-07-17 15:07:47 +12:00
G.Ambatte
f830104531 Use textContent instead of innerText 2024-07-17 13:59:00 +12:00
Trevor Buckner
d22cd88446 fix crash in metadataeditor 2024-07-15 23:47:19 -04:00
Trevor Buckner
1444581c86 pass userThemes prop to Editor -> MetadataEditor 2024-07-15 23:44:07 -04:00
Trevor Buckner
dfbd85a8ce pass userThemes as a new prop, rather than inside of the brew 2024-07-15 23:29:16 -04:00
Trevor Buckner
af5434c9b7 cleanup 2024-07-15 16:45:55 -04:00
Trevor Buckner
484b0a6dff simplify getThemeBundle() by using just one loop
Also, removes need for special handling of the "first" theme.
2024-07-15 16:38:19 -04:00
Trevor Buckner
4951b9bf1a Add async error handler to /edit and /new
Since /edit and /new endpoints now have an `await` inside that could return an error (`getUsersBrewThemes()`), asyncHandler must be added to pass errors along instead of just crashing
2024-07-13 19:46:12 -04:00
Trevor Buckner
62c619de24 userThemes need not be nested inside a Brew object 2024-07-13 19:38:51 -04:00
Trevor Buckner
44c96aad04 spacing 2024-07-13 18:11:04 -04:00
Trevor Buckner
f392216ff4 Spacing 2024-07-13 18:08:29 -04:00
Trevor Buckner
591cae0e8f more renaming engine to renderer 2024-07-13 18:08:00 -04:00
Trevor Buckner
e222811d03 Rename engine to renderer to unify naming
This value is named `renderer` everywhere else. Relabeling to a consistent name.
2024-07-13 18:06:46 -04:00
Trevor Buckner
c9b885f868 include theme as baseTheme when getting user brew themes
`baseTheme` for a user brew theme is just the `theme` value of that brew.
2024-07-13 18:01:50 -04:00
Trevor Buckner
fed65f5430 Merge branch 'master' into dependabot/npm_and_yarn/dompurify-3.1.6 2024-07-13 17:44:37 -04:00
Trevor Buckner
47f912750b Extract getting userThemes from getBrew()
`getBrew()` should do one thing only; retrieve a brew. UI elements like the list of themes available to the user are not part of a brew.

Moved into the handers for the `/edit/` and `/new/` endpoints
2024-07-13 17:44:23 -04:00
Trevor Buckner
f29a5e346e Remove id parameter from getUsersBrewThemes
Filtering out the current brew can be done later as needed; certain situations may call for retrieving the whole list.
2024-07-13 17:35:19 -04:00
Trevor Buckner
ee381c91fe Simplify getUserBrewThemes function a bit 2024-07-13 17:26:38 -04:00
Trevor Buckner
5f8d46f1b6 Reuse splitTextStyleAndMetadata from helpers.js 2024-07-13 17:09:45 -04:00
David Bolack
ade819c70c A not so light rework.
This removes the existing endpoints and replaces them with /theme.

/theme/:id - return a theme bundle containing all styling from this USER theme and any parents.
/theme/:engine/:id - return a theme bundle containing all styling from this STATIC theme and any parents

The theme bundle returns a marshalled JSON object containing:
  styles - an array of strings representing the collected styles in loading order
  snippets - an array ( currently empty ) of collected snippets.

The various bits of theme rendering code for <style> an style <link> have been swapped out with an 'onDidMount' call that loads the thendpoint and appends a series of <style> blocks to the brewRender's head.

This loses some caching advantages, but probably won't matter in the long run.
2024-07-13 12:12:05 -05:00
Trevor Buckner
c209a86f90 Merge branch 'master' into fixInkFriendlySnippet-#3563 2024-07-11 09:47:54 -04:00
Trevor Buckner
2fa3c0f311 themeClass is never used 2024-07-11 00:26:50 -04:00
Trevor Buckner
5c0a072115 userThemes passed to SnippetBar.jsx is never used 2024-07-11 00:25:11 -04:00
Trevor Buckner
29c2274a19 Unify some variable naming 2024-07-10 18:54:45 -04:00
Trevor Buckner
a6f787ea8f Remove getBrewThemeParentCSS 2024-07-10 17:56:39 -04:00
Trevor Buckner
24c86dd199 Remove unused test 2024-07-10 17:49:57 -04:00
Trevor Buckner
7eb96ee6be Simplify brewRenderer output to only emit current theme
Instead of Blank, Parent, and Theme, just make use of the @include chaining, to handle all parent themes down to and including Blank
2024-07-10 17:46:51 -04:00
Trevor Buckner
27aebf0e3b Give 5ePHB and Journal themes a baseTheme of "Blank" 2024-07-10 17:15:45 -04:00
Trevor Buckner
88578a3d16 Fix failing test 2024-07-10 14:22:42 -04:00
Trevor Buckner
28446d3ae2 Comments for theme CSS endpoints 2024-07-10 14:21:23 -04:00
Trevor Buckner
a247e50c9f renaming "get" functions
rename `getStaticTheme` to `getStaticThemeCSS`
rename `getBrewThemeWithCSS` to `getBrewThemeCSS`
rename `getBrewThemeParent` to `getBrewThemeParentCSS`

to avoid confusion with other "get" endpoints like `getBrew`, and unify naming for endpoint functions that return CSS.

Simplify `isStaticTheme` function (getting the parent theme is handled elsewhere)
2024-07-10 14:15:03 -04:00
David Bolack
656edb07ea Rework detection of user brews to look up themeid in static themes list before assuming is a user brew.
Ended up being a fairly straightforward change. A few ternaries got smooshed or inverted. Passes builtin and local tests. Need to compare on the test instance.
2024-07-08 18:12:58 -05:00
G.Ambatte
0cf79ceeb1 Merge branch 'master' into fixInkFriendlySnippet-#3563 2024-07-09 08:00:27 +12:00
G.Ambatte
7b9bd70554 Change filter to box-shadow 2024-07-08 19:57:21 +00:00
David Bolack
4b05bcac69 Merge branch 'master' into Issue_241 2024-07-08 10:16:57 -05:00
David Bolack
1555535f2e Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-07-08 10:16:05 -05:00
David Bolack
19ee3d6dbb Merge branch 'master' into Issue_241_Part_II 2024-07-08 10:14:43 -05:00
David Bolack
a413dc8d4f Merge branch 'master' into Issue_2563 2024-07-08 10:14:06 -05:00
David Bolack
74ee09397e Merge branch 'master' into Issue_2688 2024-07-08 10:08:54 -05:00
dependabot[bot]
a06aa2a103 Bump dompurify from 3.1.5 to 3.1.6
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.1.5 to 3.1.6.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.1.5...3.1.6)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-08 03:17:11 +00:00
David Bolack
ea6595d4d6 Merge branch 'master' into brew_themes_user_selection
Fixes a regression for legacy brews.
2024-07-07 12:03:15 -05:00
David Bolack
16ca52756d Merge branch 'master' into brew_themes_user_selection 2024-07-05 16:55:14 -05:00
David Bolack
645da7ae5f Merge branch 'brew_themes_user_selection' of github.com:dbolack-ab/homebrewery into brew_themes_user_selection 2024-07-05 16:54:11 -05:00
David Bolack
8570335d79 Consolidate variable redundancy. 2024-07-05 16:53:21 -05:00
G.Ambatte
c17f976385 Add HTML sanitization test step to CircleCI 2024-07-04 10:07:05 +12:00
G.Ambatte
e83e6567af Add tests via JSDOM-global 2024-07-04 10:02:45 +12:00
G.Ambatte
b638cca547 Stop evaluation tests as soon as one returns true 2024-07-04 09:32:29 +12:00
G.Ambatte
2fc5bcabb8 Merge branch 'master' into fixLinks-#3547 2024-07-04 09:13:32 +12:00
Trevor Buckner
e4bde91f6a Merge branch 'master' into brew_themes_user_selection 2024-07-02 12:04:17 -04:00
G.Ambatte
52658d6e44 Remove vue-html-secure package 2024-07-02 15:34:40 +12:00
G.Ambatte
9f3a4dc6bb Functional vue-html-secure version 2024-07-02 08:21:42 +12:00
G.Ambatte
acb10d7695 Exclude tags in FORBID_TAGS 2024-07-01 09:35:48 +12:00
G.Ambatte
fa4ced0592 Explicitly forbid script tags 2024-07-01 09:30:50 +12:00
G.Ambatte
3f1d6a5459 Re-enable DOMPurify cleaning 2024-07-01 09:30:26 +12:00
G.Ambatte
d60d902e27 Merge branch 'master' into fixLinks-#3547 2024-07-01 09:18:02 +12:00
G.Ambatte
e1c1e32a4b Return to official package; use custom addHook 2024-07-01 09:14:57 +12:00
G.Ambatte
5c2f603860 Probably terrible solution 2024-06-30 23:30:40 +12:00
G.Ambatte
47b78510df Change DOMPurify config 2024-06-29 15:35:37 +12:00
David Bolack
853f048812 Merge branch 'Issue_2563' of github.com:dbolack-ab/homebrewery into Issue_2563 2024-06-27 10:48:41 -05:00
David Bolack
4564066c63 Merge branch 'master' into Issue_2563 2024-06-27 10:44:32 -05:00
David Bolack
7e3f2a3deb Merge branch 'master' into Issue_241_Part_II 2024-06-27 10:24:48 -05:00
David Bolack
eb99acc95b Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-06-27 10:20:54 -05:00
David Bolack
ba76c51da7 Merge branch 'master' into brew_themes_user_selection 2024-06-19 19:32:04 -05:00
David Bolack
435fb6ecfe Merge branch 'Issue_2688' of github.com:dbolack-ab/homebrewery into Issue_2688 2024-06-19 19:16:52 -05:00
David Bolack
8a10fac81e Update Style based on suggestions. 2024-06-19 19:16:19 -05:00
David Bolack
7f1949a7f4 Merge branch 'master' into Issue_2688 2024-06-19 19:16:12 -05:00
David Bolack
060f28a0a6 Merge branch 'master' into Issue_241 2024-06-19 18:41:02 -05:00
David Bolack
a3f146cd53 Change the last Boneheaded hot change to something better
CTRL-SHIFT-LEFTARROW - Source Jump
CTRL-SHIFT-RIGHTARROW - Brew Jump
2024-06-19 18:39:20 -05:00
Víctor Losada Hernández
4680e7a5cc i messed up authentication entirely, this commit restores it 2024-06-16 17:21:55 +02:00
Víctor Losada Hernández
f07252d670 errors for access denied and authorization required 2024-06-16 17:14:27 +02:00
Víctor Losada Hernández
f15c831b70 proper error page 2024-06-16 17:06:18 +02:00
Víctor Losada Hernández
47b56398b1 Merge branch 'master' into Issue_2563 2024-06-15 18:09:55 +02:00
Víctor Losada Hernández
2ea2f41bd0 Merge branch 'master' into Issue_2688 2024-06-15 18:05:28 +02:00
David Bolack
7a349ae26d Remove weirdly redundant error box. 2024-06-13 18:13:32 -05:00
David Bolack
0945a5e47e Merge branch 'master' into brew_themes_user_selection 2024-06-13 15:15:30 -05:00
Víctor Losada Hernández
5232c16eb2 change div to form 2024-06-13 01:32:34 +02:00
Víctor Losada Hernández
bdfd194672 changed order of params per request 2024-06-13 01:13:38 +02:00
Víctor Losada Hernández
cb0cb32860 minor style changes & lint less file 2024-06-13 01:04:39 +02:00
Víctor Losada Hernández
1e080b30fd finally fixed the damn issue 2024-06-13 00:41:40 +02:00
Víctor Losada Hernández
fdbec6d789 Merge branch 'master' into scroll-to-element 2024-06-12 18:08:26 +02:00
David Bolack
cba57d1033 Fix and future-proof tests to use page 0 where necessary in markdown.render() calls. 2024-06-11 20:06:20 -05:00
David Bolack
1bece09339 Merge branch 'master' into Issue_1430_Unique_HeaderIDs 2024-06-11 12:59:21 -05:00
Víctor Losada Hernández
90431efbc9 "Removed ArchivePage and related files, replaced with VaultPage, updated routes and API endpoints, and made minor changes to theme configuration and error handling." 2024-06-11 00:33:36 +02:00
Víctor Losada Hernández
99b0c2b54e Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-06-10 23:25:42 +02:00
Víctor Losada Hernández
042e217872 "Refactor ArchivePage component from createClass to functional component with hooks" 2024-06-10 23:23:31 +02:00
Víctor Losada Hernández
65d6eb11dd suggested changes 2024-06-10 22:09:25 +02:00
Víctor Losada Hernández
a591763d10 "Moved iOS-specific styles from .monster.frame to a separate @supports block" 2024-06-09 00:43:11 +02:00
Víctor Losada Hernández
62bf982a73 change to browser-specific solution 2024-06-08 23:40:11 +02:00
Víctor Losada Hernández
6294b12ad5 "Removed background-blend-mode from monster stat block and updated monsterBlockBackground image URL" 2024-06-08 22:59:12 +02:00
Víctor Losada Hernández
8c09772605 Merge branch 'master' into metadata-api-endpoint 2024-06-06 01:02:10 +02:00
David Bolack
b7f88d53d0 Solve for .descriptive and .wide not getting along with suggested fix from Issue.
Uses more more direct target rather than rearrange the file.
2024-06-05 17:44:29 -05:00
David Bolack
cb8d98266c Update table of content list-item breakage rules for wide table of contents
Solves #2563
2024-06-05 17:17:49 -05:00
David Bolack
c918a79957 Integrates corrections for Document level unique Header IDs in tandum with marked-gfm-header-id updates.
Requries https://github.com/markedjs/marked-gfm-heading-id/issues/542 and an assumed version bump to work.

Validated locally.
2024-06-05 12:44:46 -05:00
David Bolack
510d8f410d Resolve timing issue with liveScroll on linking.
Checks to see if prevProps.livescroll has a proper Bool value. If not, do not brewJump() in editor.componantSDidUpdate.
2024-06-03 22:45:22 -05:00
David Bolack
ea9f9a8c36 Missed a couple of variable repalcements. 2024-06-03 02:39:20 -05:00
David Bolack
4818f70aed Add additional visual hinting to liveScroll lock. 2024-06-03 02:36:44 -05:00
David Bolack
cca79d4b17 Merge branch 'master' into Issue_241_Part_II 2024-06-03 02:29:19 -05:00
David Bolack
a715c9e1e6 Store livescrolling in local storage
Small fixes for loading the correct current state.
2024-06-03 02:26:56 -05:00
David Bolack
a48d9d295e Try binging to ctrl-X and CTRL-Shift-X which seem to somehow be available... 2024-06-02 20:23:33 -05:00
David Bolack
587831652c Merge branch 'master' into Issue_1958 2024-06-02 12:33:14 -05:00
Víctor Losada Hernández
a5f453f1e5 linting toolBar.less 2024-06-02 16:13:04 +02:00
Víctor Losada Hernández
c2170dd558 Remove line hiding toolbar in printCurrentBrew function 2024-06-02 16:12:46 +02:00
Víctor Losada Hernández
0c9958f461 "Removed '%' symbol handling from zoom input value" 2024-06-02 16:05:57 +02:00
Víctor Losada Hernández
e2a3959feb "Update brewRenderer.less: changed padding-bottom to padding-block, removed empty lines, and reformatted some styles." 2024-06-02 16:03:54 +02:00
Víctor Losada Hernández
202ea1d905 "Removed margin-bottom from brewRenderer style, added padding-bottom and updated styles in brewRenderer.less" 2024-06-02 15:59:09 +02:00
Víctor Losada Hernández
e3c1e4b6f0 "Updated toolbar.less: changed hover selector to also include focus-within" 2024-06-02 15:50:47 +02:00
David Bolack
6464f35ce9 Forgot to run npm install after merge 2024-05-31 22:40:22 -05:00
David Bolack
5442f232d5 Merge branch 'master' into brew_themes_user_selection 2024-05-31 22:32:14 -05:00
Víctor Losada Hernández
3fad8227a7 "Updated brewRenderer.jsx: added id 'zoomStyle' to style tag and changed margin-bottom from 7cm to 5cm." 2024-06-01 00:50:16 +02:00
Víctor Losada Hernández
2d051fcdc0 misstype 2024-06-01 00:42:07 +02:00
Víctor Losada Hernández
95d7ce2876 move toolbar hiding to brewrenderer.less 2024-06-01 00:41:44 +02:00
Víctor Losada Hernández
1a52acd4a9 i fixed it wrong 2024-06-01 00:37:49 +02:00
Víctor Losada Hernández
de8194d7e0 hide toolbar during printing 2024-06-01 00:34:45 +02:00
Víctor Losada Hernández
c60ddb701c this one works best 2024-05-31 21:06:39 +02:00
Víctor Losada Hernández
0e00460012 change margin bottom to fixed distance 2024-05-31 21:03:27 +02:00
Víctor Losada Hernández
ed92628012 udpate input zoom 2024-05-31 21:02:03 +02:00
Víctor Losada Hernández
12de8c5221 fix last page navigation 2024-05-31 21:00:01 +02:00
Víctor Losada Hernández
afa0571382 fix page displacement 2024-05-31 20:57:09 +02:00
Víctor Losada Hernández
75c592b437 "Update onPageChange argument in nextPage button onClick handler" 2024-05-31 20:28:34 +02:00
Víctor Losada Hernández
90b504d67d Oops 2024-05-31 20:26:12 +02:00
Víctor Losada Hernández
8efea112b4 "Updated scrollToPage argument to add 1 to pageNumber" 2024-05-31 20:22:14 +02:00
Víctor Losada Hernández
000c3db8cd fixed page error 2024-05-31 20:14:41 +02:00
Víctor Losada Hernández
f23c0bccbc "Added onKeyPress event handler to zoom input and page number input to blur the target on Enter key press." 2024-05-31 19:46:40 +02:00
Víctor Losada Hernández
69db1e2cb7 change page works, added change zoom via input too 2024-05-31 19:43:09 +02:00
Víctor Losada Hernández
acbdd1b801 "Removed iframe parameter from scrollToPage and getPageContainingElement functions, instead getting iframe element by id 'BrewRenderer' inside the functions." 2024-05-31 17:13:29 +02:00
Víctor Losada Hernández
933dc372d2 "Refactor scrollToPage function to retrieve iframe element internally and add page not found logging" 2024-05-31 17:10:35 +02:00
Víctor Losada Hernández
d012a09346 "Refactor BrewRenderer: updated iframe handling and scrolling logic in useEffect and scrollToPage function" 2024-05-31 17:06:47 +02:00
Víctor Losada Hernández
3cca38302a "Refactor BrewRenderer component: removed unnecessary code, reorganized useEffect hooks, and simplified getPageContainingElement function." 2024-05-31 17:00:03 +02:00
Víctor Losada Hernández
f9352a94c6 "Refactor BrewRenderer: simplify URL param extraction, remove iframe existence checks, and update scrollIntoView behavior" 2024-05-31 16:47:17 +02:00
Víctor Losada Hernández
1add97b1b2 scrolls to page 100 ms after page load 2024-05-31 16:38:08 +02:00
Víctor Losada Hernández
176766dfe7 change in themes.json apparently 2024-05-31 16:25:29 +02:00
Víctor Losada Hernández
6fb185a964 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into pdf-tools 2024-05-31 16:23:55 +02:00
Víctor Losada Hernández
1442414299 scroll to page 2024-05-31 16:23:47 +02:00
Víctor Losada Hernández
f6161abf52 bottom margin to prevent bottom clip 2024-05-29 16:23:32 +02:00
Víctor Losada Hernández
4543881808 functional zoom 2024-05-28 08:51:23 +02:00
Víctor Losada Hernández
6e0aff525f Updated rate limiter window name 2024-05-25 20:51:44 +02:00
Víctor Losada Hernández
748c25aae4 "Added express-rate-limit package and implemented rate limiting for admin API login attempts" 2024-05-24 20:42:25 +02:00
Víctor Losada Hernández
609f5a3330 more logs 2024-05-23 14:08:37 +02:00
Víctor Losada Hernández
058d70ed82 auto, not scroll 2024-05-23 13:37:23 +02:00
Víctor Losada Hernández
cbdf06f39d oops 2024-05-23 13:35:00 +02:00
Víctor Losada Hernández
6f6c142aa2 fixes scrolling error 2024-05-23 13:32:09 +02:00
Víctor Losada Hernández
72cb8e7db9 remove console logs and add forced space to brew count 2024-05-23 13:18:07 +02:00
Víctor Losada Hernández
133295c225 big changes to the UI 2024-05-22 20:10:54 +02:00
Víctor Losada Hernández
54efc18ad4 minimum range text to 3 2024-05-22 19:55:20 +02:00
Víctor Losada Hernández
43f77dc525 fix valid check 2024-05-22 19:49:06 +02:00
Víctor Losada Hernández
34d37b24f1 "Update text in 'noBrews' div from 'Whenever you want, just start typing...' to 'No search yet'" 2024-05-22 12:33:11 +02:00
Víctor Losada Hernández
1e6427ca56 non selection , as per request 2024-05-22 12:28:57 +02:00
Víctor Losada Hernández
b9152867b8 "Refactor UpdateURL function" 2024-05-22 12:26:47 +02:00
Víctor Losada Hernández
879a1f5a57 fix page size to count 2024-05-22 08:51:49 +02:00
Víctor Losada Hernández
0f9ba1a5ae Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-05-22 08:23:53 +02:00
Víctor Losada Hernández
d96d3c501e logs 2024-05-22 08:22:19 +02:00
Víctor Losada Hernández
215888baf4 "Simplified conditional statement for displaying total brews count" 2024-05-22 08:21:00 +02:00
Víctor Losada Hernández
d56ea62b5e "Refactor loadPage function in ArchivePage component to fix wrong load of data" 2024-05-22 08:17:12 +02:00
Víctor Losada Hernández
888cf55b3d should render an icon while loading total count 2024-05-22 08:13:21 +02:00
Víctor Losada Hernández
4d7b1864d9 This should fix correct load on URL, will probably not work 2024-05-22 08:02:50 +02:00
Víctor Losada Hernández
319746f6cd "Removed options from pageSize select, added new options, and updated CSS selector for searchButton" 2024-05-22 07:58:09 +02:00
Víctor Losada Hernández
8fd165a79b form changes 2024-05-21 23:43:56 +02:00
Víctor Losada Hernández
ecfdada810 fix damn error finally 2024-05-21 12:24:47 +02:00
Víctor Losada Hernández
68c3e1ba84 log at will 2024-05-21 12:16:07 +02:00
Víctor Losada Hernández
efda06ebe5 console log to find the issue 2024-05-21 12:09:41 +02:00
Víctor Losada Hernández
e9b85e1a9a damn totalBrews won't go away 2024-05-21 12:06:08 +02:00
Víctor Losada Hernández
f9d19c75b2 change renderPagination order of operations and fix pagination not loading properly 2024-05-21 11:57:48 +02:00
Víctor Losada Hernández
bc9ab284d8 Initial UI 2024-05-21 08:01:50 +02:00
David Bolack
e69132b40a Constant a lookup. 2024-05-20 20:31:30 -05:00
David Bolack
77450ed334 Merge branch 'master' into Issue_241_Part_II 2024-05-20 20:03:23 -05:00
David Bolack
eb809ca375 Merge branch 'master' into Issue_241 2024-05-20 17:59:34 -05:00
David Bolack
54d2709d6a Merge 2024-05-20 17:58:22 -05:00
David Bolack
916bd5f4d6 Merge branch 'master' into brew_themes_user_selection 2024-05-20 17:56:21 -05:00
David Bolack
835ca0de32 WIP 2024-05-20 16:21:02 -05:00
David Bolack
f675fd130f Merge branch 'master' into Issue_1958 2024-05-20 13:36:41 -05:00
Víctor Losada Hernández
21244fba58 "Removed lodash import, simplified boolean assignments, refactored API request and error handling, and removed unused variables in ArchivePage component." 2024-05-19 23:45:12 +02:00
Víctor Losada Hernández
55dd4efe41 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-05-19 23:21:47 +02:00
David Bolack
bacdd65025 Add a CR. 2024-05-19 11:52:16 -05:00
David Bolack
40c8b04a98 Merge branch 'master' into Issue_241 2024-05-19 11:48:10 -05:00
David Bolack
07f2e8ba4f Merge branch 'master' into Issue_241_Part_II 2024-05-19 11:20:09 -05:00
David Bolack
86887b536e Update Jump keys to match parent PR and shift live scrolling to scroll-lock.
Needs non-PC testing.
2024-05-19 11:16:50 -05:00
David Bolack
c0cc27a750 Change Jump hotkeys to M ( move ) bindings. 2024-05-19 11:12:19 -05:00
David Bolack
b7dc47fe9e Add a Live Scroll lock/unlock below Brew/Source Jump buttons.
The button displays the *next* state of the toggle. IE, if the current state is locked ( Live scrolling is active ) the icon is unlock with a corresponding mouse-over.

It may be desirable to invert this.
2024-05-18 22:17:29 -05:00
Víctor Losada Hernández
9343f11366 Merge branch 'master' into metadata-api-endpoint 2024-05-19 00:11:34 +02:00
Víctor Losada Hernández
6e08fcca80 minor changes 2024-05-18 23:47:29 +02:00
Víctor Losada Hernández
3d0a9ea805 "Update ArchivePage: erase brewcount when new query, modify error messages for 503 and 500 status codes" 2024-05-18 23:19:25 +02:00
Víctor Losada Hernández
a711f8eb89 remove regex search 2024-05-18 23:07:43 +02:00
David Bolack
8ece54701d Add live scrolling to keep the preview in sync with editor position.
This catchs CTRL-HOME, CTRL-END, and mouseclicks.

It tests for changes on arrow keys and enter.

Not sure if it's the best way to do this, but it works quickly on a large, crappy brew.
2024-05-18 01:44:42 -05:00
David Bolack
9b0db15083 Add Jump To hotkeys
This binds CTRL/META-J to brewJump and SHIFT-CTRL/META-J to sourceJump.
2024-05-17 22:10:28 -05:00
David Bolack
c6f62142e1 Change the ID used for User Brews to the shareId for future-proofing. 2024-05-17 20:53:06 -05:00
Víctor Losada Hernández
243038474e Initial commit 2024-05-17 21:23:31 +02:00
Víctor Losada Hernández
97ef56f905 small changes, tips and style 2024-05-14 11:10:48 +02:00
Víctor Losada Hernández
124af97cc8 extra page buttons linked to relevant pages 2024-05-14 10:49:10 +02:00
Víctor Losada Hernández
021ac68400 Update archive page to use pagination with page numbers and ellipses
* Change the way pagination is handled on the archive page
* Display page links for 10 pages max
2024-05-14 10:44:16 +02:00
Víctor Losada Hernández
4b10686336 simplify logic 2024-05-14 09:49:14 +02:00
Víctor Losada Hernández
153812c6e5 simplify console log and remove unused code 2024-05-14 09:36:59 +02:00
Víctor Losada Hernández
9aa3ebe872 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-05-14 09:31:40 +02:00
Víctor Losada Hernández
e23166e1d5 when did i change this? 2024-05-14 09:31:22 +02:00
David Bolack
69f01b282a CSS Tweaks for Theme Selector
Add 5e-Cleric's suggestsions to acvoid the title overflowing over the preview.
2024-05-13 22:33:58 -05:00
David Bolack
66e39d9c65 Update Theme Selector display
For User/Brew Themes, display the first author instead of Brew/V3 in the first column.
2024-05-13 22:24:41 -05:00
David Bolack
8c5f4e0605 Brew Theme Fixes.
This adds the User Brew themes, where applicible, to the /new path.

This adds a semi-graceful failure to the metadata panel when a Brew Theme is declared as used but is not present.

More gracefully handles loading with themes not present.
2024-05-13 11:14:35 -05:00
Víctor Losada Hernández
a89b575b26 archive 2.0 2024-05-13 13:37:53 +02:00
David Bolack
ed210da4af Merge branch 'master' into brew_themes_user_selection 2024-05-12 12:08:16 -05:00
David Bolack
a69d251f53 Merge branch 'master' into Issue_1958 2024-05-12 10:37:20 -05:00
David Bolack
b6c2f96b82 Change tag filtering for theme detection to require meta prefix 2024-05-10 01:40:01 -04:00
Víctor Losada Hernández
5eeac603db why didn't i think about this sooner 2024-05-09 08:24:27 +02:00
David Bolack
6f7a657b59 Merge branch 'brew_themes_user_selection' of github.com:dbolack-ab/homebrewery into brew_themes_user_selection 2024-05-08 12:52:01 -05:00
David Bolack
65495b4e7c Prevent Legacy renderer brews from being listed as themes. 2024-05-08 12:51:10 -05:00
Víctor Losada Hernández
cca0f3b4dc Revert "pagination controls update search terms"
This reverts commit 9966e6322d.
2024-05-08 15:51:31 +02:00
Víctor Losada Hernández
22f4dade4f default value to page size 2024-05-08 15:51:14 +02:00
Víctor Losada Hernández
e30a0c3dce page size log to track issue 2024-05-08 15:41:44 +02:00
Víctor Losada Hernández
9966e6322d pagination controls update search terms 2024-05-08 15:33:27 +02:00
Víctor Losada Hernández
02450982c1 fix brewCollection issue 2024-05-08 13:32:03 +02:00
David Bolack
07ca134d98 Merge pull request #1 from Gazook89/dropdownTextures-User-Themes
Add dropdownTexture for user theme options
2024-05-07 16:39:13 -05:00
David Bolack
dde8e28d07 Merge branch 'brew_themes_user_selection' into dropdownTextures-User-Themes 2024-05-07 16:38:56 -05:00
David Bolack
872ee339da Clean up console logs
Eliminate erroronous theme pulldown texture load.
2024-05-07 12:13:57 -05:00
Gazook89
295fea7581 Add dropdownTexture for user theme options
If a user theme document has a thumbnail, this will include that thumbnail as a dropdown texture in the options.
2024-05-07 11:00:20 -05:00
Víctor Losada Hernández
f9f2e604c0 linting and remove async conflict 2024-05-07 10:14:46 +02:00
David Bolack
f936b8b12b Update User brew endpoint tests 2024-05-06 20:28:46 -05:00
David Bolack
9f04c34b06 Missed $ 2024-05-06 20:07:33 -05:00
David Bolack
c9d416fec0 Small User Brew theme changes.
Move the Static Theme shortcut to getBrewThemeWithCSS to drop an unneeded URL load.

Change the comment in the CSS to refer to the shareURL for the theme
instead of its name if it is a user theme.
2024-05-06 19:39:27 -05:00
Víctor Losada Hernández
40ac8b1909 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-05-07 00:12:26 +02:00
Víctor Losada Hernández
f1a2037bca page is sometimes a string?? 2024-05-06 23:40:31 +02:00
Víctor Losada Hernández
ded78c6639 better error handling in jsx 2024-05-06 23:32:18 +02:00
Víctor Losada Hernández
51fcb59f09 debugging 500 errir catching 2024-05-06 23:26:02 +02:00
Víctor Losada Hernández
e75c556443 use $text instead 2024-05-06 22:59:09 +02:00
David Bolack
3dde6a098c Test code to reduce duplicate theme loading
This shorts out loading of 5ePHB and/or blank from getBrewThemeParent
2024-05-06 12:12:46 -05:00
David Bolack
ef25139ffe Merge branch 'master' into brew_themes_user_selection 2024-05-06 12:04:38 -05:00
Víctor Losada Hernández
752b2caaf4 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-05-06 13:45:06 +02:00
David Bolack
88ccb955ce Merge branch 'master' into brew_themes_user_selection 2024-04-30 20:11:32 -05:00
David Bolack
980ed8e265 Merge branch 'master' into brew_themes_user_selection 2024-04-20 21:55:59 -05:00
David Bolack
1292d9ad9b Merge branch 'master' into brew_themes_user_selection 2024-04-18 21:13:01 -05:00
Víctor Losada Hernández
3c84143511 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-04-02 14:40:24 +02:00
David Bolack
57f0aefbc8 Merge branch 'master' into brew_themes_user_selection 2024-03-25 20:38:28 -05:00
David Bolack
f2f32c35ea Ensure shared pages work with user themes. 2024-03-10 11:54:48 -05:00
David Bolack
d4770f16e3 Merge branch 'master' into brew_themes_user_selection 2024-03-09 20:25:24 -06:00
David Bolack
7ed48f3e70 Merge branch 'master' into Issue_1958 2024-03-09 20:12:03 -06:00
David Bolack
627b4ace0f Merge branch 'master' into Issue_1958 2024-03-06 23:42:11 -06:00
David Bolack
e487f9a951 Fix remaining jest issues 2024-03-06 23:27:43 -06:00
David Bolack
eb4ecf853b Fix Jest issues I was able to understand 2024-03-06 22:50:24 -06:00
David Bolack
54e2deaddc Merge branch 'master' into brew_themes_user_selection 2024-03-06 19:28:37 -06:00
David Bolack
1ac510af3d Heroku debug 2024-03-06 19:24:16 -06:00
David Bolack
a666c8def3 Heroku debug 2024-03-06 19:20:16 -06:00
David Bolack
33933ef212 Attempted fix on access 2024-03-06 19:14:16 -06:00
David Bolack
d9dade7181 Fix User Brew display label in metadata editor 2024-03-06 19:04:12 -06:00
David Bolack
87502f4249 Heavy rework for usertheme parents. 2024-03-06 18:55:12 -06:00
David Bolack
9adafbd473 more heroku debug 2024-03-06 14:12:13 -06:00
David Bolack
47ea2f6ed7 more heroku debug 2024-03-06 14:04:16 -06:00
David Bolack
e2ba0ec059 more heroku debug 2024-03-06 13:59:36 -06:00
David Bolack
870cbc103d more heroku debug 2024-03-06 13:57:32 -06:00
David Bolack
dfca664f6e more heroku debug 2024-03-06 13:53:54 -06:00
David Bolack
00cfd427b1 more heroku debug 2024-03-06 13:47:40 -06:00
David Bolack
e639a32822 more heroku debug 2024-03-06 13:41:58 -06:00
David Bolack
8765bc800d more heroku debug 2024-03-06 13:38:48 -06:00
David Bolack
1dc73a951e more heroku debug 2024-03-06 13:35:08 -06:00
David Bolack
317b80bf4d more heroku debug 2024-03-06 13:20:57 -06:00
David Bolack
2aaae95e89 more heroku debug 2024-03-06 13:16:57 -06:00
David Bolack
0580e45af9 more heroku debug 2024-03-06 13:11:49 -06:00
David Bolack
0dbf6453ac more heroku debug 2024-03-06 13:04:03 -06:00
David Bolack
695324832c more heroku debug 2024-03-06 12:56:33 -06:00
David Bolack
ac4c84e7a4 config file fix 2024-03-06 12:44:20 -06:00
David Bolack
18aa453bb0 Rearrange and leverage getBrew 2024-03-06 12:38:00 -06:00
David Bolack
17f78169f2 More debug 2024-03-06 12:03:27 -06:00
David Bolack
6f6a06c8c3 More debug 2024-03-06 11:00:43 -06:00
David Bolack
79a4291153 More debug 2024-03-06 10:37:10 -06:00
David Bolack
a54fb98d4e Additional debugging 2024-03-06 10:28:09 -06:00
David Bolack
a3549ae694 Merge branch 'master' into brew_themes_user_selection 2024-03-06 09:35:10 -06:00
David Bolack
42c441f534 Merge branch 'master' into brew_themes_user_selection 2024-03-04 16:54:13 -06:00
David Bolack
f2d5a8df99 Merge branch 'master' into Issue_1958 2024-03-04 11:45:53 -06:00
David Bolack
a924f53320 Merge branch 'master' into brew_themes_user_selection 2024-03-03 22:11:35 -06:00
David Bolack
4f90f92b38 Additional theme based error checking. 2024-02-28 15:08:00 -06:00
David Bolack
753b3befad Fix issue with empty theme ( /faq ) 2024-02-28 14:53:40 -06:00
David Bolack
544bc9bd01 Catch bad assumption in unlogged saves 2024-02-28 08:32:15 -06:00
David Bolack
1a467565c1 Merge branch 'master' into brew_themes_user_selection 2024-02-27 21:32:33 -06:00
David Bolack
562daf9b04 Handle some statics 2024-02-27 21:13:22 -06:00
David Bolack
8f15887c03 Cleanup of console logging 2024-02-27 20:51:59 -06:00
David Bolack
7384cdc241 My god it works 2024-02-27 20:20:43 -06:00
David Bolack
56851f2c2d Edit working - with noise. 2024-02-27 19:33:33 -06:00
David Bolack
50c9d95ce0 WIP trying to debug theme selection. 2024-02-27 17:30:14 -06:00
David Bolack
4f4659b0e2 Cleaned up noise in homebrew.api.js 2024-02-27 13:57:58 -06:00
David Bolack
7b3a1eb4ff Functional user theme loading though noising console 2024-02-27 13:41:51 -06:00
David Bolack
2456432844 Exclude self from brew themes list to prevent circular ref. 2024-02-23 17:12:54 -06:00
David Bolack
3e66647f9f Fix @import loading on Chrome. 2024-02-23 14:43:29 -06:00
David Bolack
6d6571be0b Merge branch 'master' into brew_themes_user_selection 2024-02-23 13:46:56 -06:00
Víctor Losada Hernández
dad4cd90ca Merge branch 'master' into addCSSRoute-#1097 2024-02-23 20:23:19 +01:00
David Bolack
f9307986cd WIP
@import statements are just not working. Uploaded for other eyes.
2024-02-22 23:06:40 -06:00
David Bolack
f60090e5fa Update Theme Picker to use Brews tagged as a theme
This updates the theme picker to include brews tagged as themes owned by
the user.

Some supporting functions were updated. User themes are loaded on /edit
and added to the request.
2024-02-22 21:12:56 -06:00
Víctor Losada Hernández
094ad3bd59 -proj in countdocs 2024-02-21 08:07:46 +01:00
David Bolack
ae2bb3a028 Add missing style.css 2024-02-20 23:26:09 -06:00
David Bolack
c319d6bcfa Consolidate and add theme parent walking
This consolidates the style/theme endpoint to a singular method, adds
interpretation of static themes, and allow parent theme recursion.

I am not 100% sure this will order styles correctly.
2024-02-20 23:15:37 -06:00
David Bolack
e2ef9b8122 Report Theme title with CSS
This adds a comment/field ( depending on endpoint ) that reports the
name of the Brew being used as a theming source.
2024-02-20 16:44:17 -06:00
David Bolack
8e48df5de1 Partial Code coverage for new endpoints 2024-02-18 12:45:14 -06:00
David Bolack
a3b1d7fb7c Use a brew as a theme, three ways.
This has been implemented three different ways to allow for comparison
and discussion

- /api/css/:id : This returns the style frontmatter of the referenced
  document as a text/css document.
/api/theme/:id : This returns an object with the reference'd object's
theme and style frontmatter.
/api/csstheme/:id : This returns the stylye frontmatter of the
referenced document as a text/css document and adds the theme as an
@import ( if not using the legacy renderer )
2024-02-17 11:01:21 -06:00
Víctor Losada Hernández
01e3cd0296 fix notitle search and catch 404? 2024-02-15 17:22:20 +01:00
Víctor Losada Hernández
fd6109099a catch catch catch 2024-02-15 16:59:17 +01:00
Víctor Losada Hernández
8c07b12bb0 catch error codes 2024-02-15 16:56:09 +01:00
Víctor Losada Hernández
eb404b8e5b where is my 503 error code 2024-02-15 16:51:20 +01:00
Víctor Losada Hernández
0fdb5e83cf if this renders null i don't understand anything 2024-02-15 16:44:03 +01:00
Víctor Losada Hernández
2a780bc482 503 2024-02-15 16:36:10 +01:00
Víctor Losada Hernández
f61b664687 503 log 2024-02-15 16:32:50 +01:00
Víctor Losada Hernández
04844a4422 you know the deal 2024-02-15 16:27:50 +01:00
Víctor Losada Hernández
3afc9f83d9 where the hell did i lose the error handling 2024-02-15 16:23:37 +01:00
Víctor Losada Hernández
e08435568c don't search on reload without title 2024-02-15 16:20:08 +01:00
Víctor Losada Hernández
1a80a74d4f more error handling 2024-02-15 16:15:38 +01:00
Víctor Losada Hernández
9c53541cbd searching animation 2024-02-15 15:53:26 +01:00
Víctor Losada Hernández
62db393969 proper error handling(i think) 2024-02-15 15:50:27 +01:00
Víctor Losada Hernández
d7c9ab43bc more tests 2024-02-15 15:34:10 +01:00
Víctor Losada Hernández
fcb4c722c6 test 404 error 2024-02-15 15:28:36 +01:00
Víctor Losada Hernández
7626f63beb page numberas as links 2024-02-15 15:16:01 +01:00
Víctor Losada Hernández
a6e45c7fd1 Merge branch 'master' into experimental-development 2024-02-15 13:49:43 +01:00
Víctor Losada Hernández
2658831e83 pagination controls don't reset search 2024-02-15 13:45:31 +01:00
Víctor Losada Hernández
ffdbe46a23 catch 503 without title query 2024-02-15 10:43:12 +01:00
Víctor Losada Hernández
6a11cd0e28 renderer filter query 2024-02-15 10:34:39 +01:00
Víctor Losada Hernández
153ab63393 pagesize as input 2024-02-15 08:48:47 +01:00
Víctor Losada Hernández
ea1855485c css fixes 2024-02-15 01:27:05 +01:00
Víctor Losada Hernández
3427fa1e94 total brews found 2024-02-15 01:26:54 +01:00
Víctor Losada Hernández
46262c56db 503 catch 2 2024-02-15 01:15:00 +01:00
Víctor Losada Hernández
3482d92ab6 catch 503 error 2024-02-15 01:10:28 +01:00
Víctor Losada Hernández
74ac8f9ffa quickfix 2024-02-13 10:52:12 +01:00
Víctor Losada Hernández
7e289950fa Merge branch 'experimental-development' of https://github.com/5e-Cleric/homebrewery into experimental-development 2024-02-13 10:48:24 +01:00
Víctor Losada Hernández
9fc8af6553 pagination controls render separately 2024-02-13 10:48:19 +01:00
G.Ambatte
7ffc02c3e5 Reset searching state on error 2024-02-13 13:25:45 +13:00
Víctor Losada Hernández
2f323cde8a remove unused logic from loadpage 2024-02-12 23:54:15 +01:00
Víctor Losada Hernández
534131d994 edit console logs and change totalDocs logic to count correctly 2024-02-12 23:54:00 +01:00
Víctor Losada Hernández
d233e2b4a5 css fix, pagination controls basic look 2024-02-12 23:18:37 +01:00
Víctor Losada Hernández
05a7defcb8 remove brewCount useless element 2024-02-12 23:18:24 +01:00
G.Ambatte
eeec24ae78 Change fetch to use request-middleware instead 2024-02-13 09:14:31 +13:00
G.Ambatte
1d778e3249 Update API route 2024-02-13 09:13:47 +13:00
G.Ambatte
3bb44d8a17 Lint clean up 2024-02-13 09:06:33 +13:00
Víctor Losada Hernández
71c52b4587 fix html response 2024-02-12 08:44:18 +01:00
Víctor Losada Hernández
fe449abb47 trying to figure out pagination 2024-02-10 16:41:39 +01:00
David Bolack
0d8026436c Merge branch 'master' into Issue_1958 2024-02-07 20:10:04 -06:00
Víctor Losada Hernández
46d1f89b77 minor fixes 2024-01-29 00:12:14 +01:00
Víctor Losada Hernández
bf1f2054de minor fixes 2024-01-28 16:14:54 +01:00
Víctor Losada Hernández
399caaaeff typo 2024-01-28 16:11:32 +01:00
Víctor Losada Hernández
27b4176e23 initial screen 2024-01-28 16:08:44 +01:00
Víctor Losada Hernández
a8bc6b4e1d h2 to h3 2024-01-28 16:04:21 +01:00
Víctor Losada Hernández
3ca8f72762 brewCount 2024-01-28 16:02:19 +01:00
Víctor Losada Hernández
8aec5dbba6 error 500 catch and show 2024-01-28 15:57:51 +01:00
Víctor Losada Hernández
cccebd8494 title and no brews UI 2024-01-28 11:18:37 +01:00
Víctor Losada Hernández
5fbbd92ea7 limit to 1000 2024-01-28 01:12:46 +01:00
Víctor Losada Hernández
81f26e0892 exclude last fix 2024-01-28 00:55:22 +01:00
Víctor Losada Hernández
9366284e1d quick fix 2024-01-28 00:26:35 +01:00
Víctor Losada Hernández
9aa5eea8c9 exclude fields and add a time limit 2024-01-27 23:31:56 +01:00
Víctor Losada Hernández
20f61bff07 limit to 2000 2024-01-27 21:46:28 +01:00
Víctor Losada Hernández
625819da91 Merge branch 'master' of https://github.com/naturalcrit/homebrewery into experimental-development 2024-01-27 19:14:48 +01:00
Víctor Losada Hernández
2c691d84f2 author fix 3 2024-01-27 19:14:38 +01:00
Víctor Losada Hernández
4630d2640b author another fix 2024-01-27 17:29:16 +01:00
Víctor Losada Hernández
043f24d5ca invited authors is not a thing 2024-01-27 16:56:38 +01:00
Víctor Losada Hernández
87e18c0521 no authors fix 2024-01-27 16:56:28 +01:00
Víctor Losada Hernández
7e30f860b2 typo fix 2024-01-27 16:26:06 +01:00
Víctor Losada Hernández
0ac0ffe53d limit to 3000 2024-01-27 16:25:06 +01:00
Víctor Losada Hernández
ae4e1b55e6 minor changes 2024-01-27 16:24:45 +01:00
Víctor Losada Hernández
756ced088c Merge branch 'experimental-development' of https://github.com/5e-Cleric/homebrewery into experimental-development 2024-01-27 14:31:34 +01:00
Víctor Losada Hernández
8ce6b22be7 reject modernity, embrace tradition 2024-01-27 14:31:32 +01:00
Trevor Buckner
6184d64f89 Merge branch 'master' into pr/3263 2024-01-25 16:43:21 -05:00
David Bolack
8656feba44 Merge branch 'master' into Issue_1958 2024-01-25 00:18:47 -06:00
Víctor Losada Hernández
c00c2626b4 Merge branch 'master' into experimental-development 2024-01-24 22:56:30 +01:00
Víctor Losada Hernández
89fddd0210 limit search and adapt ui 2024-01-24 21:15:26 +01:00
Víctor Losada Hernández
0c167d803c limit the search 2024-01-24 21:15:00 +01:00
Víctor Losada Hernández
c50042c1e7 i love grid template area 2024-01-23 22:55:36 +01:00
Víctor Losada Hernández
0dc1b46466 stying updates, agnostic theme 2024-01-23 19:08:57 +01:00
Víctor Losada Hernández
4ed9fc7d0e fix url params 2024-01-23 18:35:09 +01:00
Víctor Losada Hernández
162929bdca trying to catch url with query 2024-01-23 14:02:27 +01:00
Víctor Losada Hernández
54a2f6940c from admin to archive api 2024-01-23 10:40:53 +01:00
Víctor Losada Hernández
0dff59d793 linting and space issues 2024-01-23 08:07:51 +01:00
Víctor Losada Hernández
7951c4a03a basic ui and small changes 2024-01-23 00:20:18 +01:00
Víctor Losada Hernández
66fd56fccb basic functionality 2024-01-22 23:52:42 +01:00
Víctor Losada Hernández
da699e999f basic looks 2024-01-22 23:20:36 +01:00
Víctor Losada Hernández
c6a5f50c76 admin page fix 2024-01-22 17:22:54 +01:00
Víctor Losada Hernández
74c7395ab9 admin look by title 2024-01-22 16:59:45 +01:00
Trevor Buckner
e9a76dd018 Use existing dependency fs-extra instead of adding new one 2023-12-04 22:28:48 -05:00
Trevor Buckner
db0f75c852 Merge branch 'master' into pr/3132 2023-12-04 22:26:05 -05:00
David Bolack
0db6ffe340 Merge branch 'master' into Issue_1958 2023-11-10 23:23:55 -06:00
David Bolack
1b855108bf Correct omitted static path 2023-11-07 21:26:11 -06:00
David Bolack
ffe12ebee7 Add local statics for images and typefaces
This solves issue #1958.

Add static paths /staticImages and /staticFonts

If a local environment is detected ( per existing loginc for login )
paths are added using the values in HB_IMAGES and HB_FONTS or the default values of /staticImages and /staticFonts respectively.
2023-11-07 20:21:19 -06:00
G.Ambatte
0a309ad0e1 Remove debugging console.log 2023-10-01 21:46:52 +13:00
G.Ambatte
52b0ae0400 Basic functionality pass 2023-10-01 21:35:50 +13:00
G.Ambatte
e211b0858d Merge branch 'master' into experimentalNotificationDB 2023-08-28 07:51:31 +12:00
G.Ambatte
c8ac3f36fd Merge branch 'master' into experimentalNotificationDB 2023-07-16 09:41:05 +12:00
G.Ambatte
8c0cf4ccd4 Merge branch 'master' into experimentalNotificationDB 2023-07-06 17:55:00 +12:00
G.Ambatte
79eb4d8a9a Merge branch 'master' into experimentalNotificationDB 2023-06-10 14:27:49 +12:00
G.Ambatte
52d5d17561 Merge branch 'master' into experimentalNotificationDB 2023-03-24 07:56:24 +13:00
G.Ambatte
0fc3e03e95 Merge branch 'master' into experimentalNotificationDB 2023-03-12 22:30:53 +13:00
G.Ambatte
28cadcad06 Merge branch 'master' into experimentalNotificationDB 2023-02-22 16:14:19 +13:00
G.Ambatte
1fd8648602 Merge branch 'naturalcrit:master' into experimentalNotificationDB 2023-02-19 15:22:19 +13:00
G.Ambatte
66e10f3b4e Merge branch 'master' into experimentalNotificationDB 2023-02-14 13:00:02 +13:00
G.Ambatte
da0372e44c WIP commit 2023-01-23 15:18:50 +13:00
G.Ambatte
a4e6b2358a Merge branch 'master' into experimentalNotificationDB 2023-01-21 17:59:32 +13:00
G.Ambatte
24adbdc429 Change model to use defaults rather than mergeWith 2023-01-15 23:28:54 +13:00
G.Ambatte
ccd5cacb0c Stub notification deletion function 2023-01-15 23:25:17 +13:00
G.Ambatte
5e2171ceb1 Remove debugging console.log calls 2023-01-15 22:21:06 +13:00
G.Ambatte
b00a962e77 Fix typo 2023-01-15 20:44:41 +13:00
G.Ambatte
c518fc2d23 Merge branch 'naturalcrit:master' into experimentalNotificationDB 2023-01-15 13:55:25 +13:00
G.Ambatte
ca2582fdbd Merge branch 'experimentalNotificationDB' of https://github.com/G-Ambatte/homebrewery into experimentalNotificationDB 2023-01-15 13:54:28 +13:00
G.Ambatte
04916d8931 Initial notificationAdd functionality 2023-01-15 13:54:19 +13:00
G.Ambatte
f781c2bd56 Merge branch 'master' into experimentalNotificationDB 2023-01-07 10:29:54 +13:00
G.Ambatte
8adf5ce463 Add user-specified DismissKey to Add Notification 2023-01-06 13:53:16 +13:00
G.Ambatte
94afbe5417 Merge branch 'master' into experimentalNotificationDB 2023-01-06 13:51:37 +13:00
G.Ambatte
9e169aba91 Tweak LookUp title 2023-01-05 10:56:50 +13:00
G.Ambatte
f5c7761c61 Add styling to active tab 2023-01-05 10:52:24 +13:00
G.Ambatte
ec040cc2bb Add DisplayNames 2023-01-05 10:04:45 +13:00
G.Ambatte
42125f4041 Update Notification schema 2023-01-05 09:03:51 +13:00
G.Ambatte
a499bb3a54 Add basic Notification Lookup functionality 2023-01-04 23:32:35 +13:00
G.Ambatte
35b4c354f2 Add key prop to Admin tabs 2023-01-04 23:20:11 +13:00
G.Ambatte
b8fd8a7a86 Add Notification lookup to Admin API 2023-01-04 22:52:37 +13:00
G.Ambatte
620cb95ae8 Initial pass at Notification Mongoose model 2023-01-04 22:50:24 +13:00
G.Ambatte
f66664a3e2 Tabify Admin page, add Notification tab 2023-01-04 22:49:38 +13:00
G.Ambatte
d7ee004127 Update Admin pages 2023-01-04 22:08:44 +13:00
G.Ambatte
4a449c7895 Update Buffer method 2023-01-04 22:08:22 +13:00
145 changed files with 10055 additions and 5762 deletions

View File

@@ -10,7 +10,7 @@ orbs:
jobs:
build:
docker:
- image: cimg/node:20.8.0
- image: cimg/node:20.17.0
- image: mongo:4.4
working_directory: ~/homebrewery
@@ -27,7 +27,7 @@ jobs:
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: sudo npm install -g npm@10.2.0
- run: sudo npm install -g npm@10.8.2
- node/install-packages:
app-dir: ~/homebrewery
cache-path: node_modules
@@ -45,7 +45,7 @@ jobs:
test:
docker:
- image: cimg/node:20.8.0
- image: cimg/node:20.17.0
working_directory: ~/homebrewery
parallelism: 1
@@ -67,12 +67,18 @@ jobs:
- run:
name: Test - Definition Lists
command: npm run test:definition-lists
- run:
name: Test - Hard Breaks
command: npm run test:hard-breaks
- run:
name: Test - Variables
command: npm run test:variables
- run:
name: Test - Routes
command: npm run test:route
- run:
name: Test - HTML sanitization
command: npm run test:safehtml
- run:
name: Test - Coverage
command: npm run test:coverage

View File

@@ -1,79 +0,0 @@
module.exports = {
root : true,
parserOptions : {
ecmaVersion : 2021,
sourceType : 'module',
ecmaFeatures : {
jsx : true
}
},
env : {
browser : true,
node : true
},
plugins : ['react', 'jest'],
rules : {
/** Errors **/
'camelcase' : ['error', { properties: 'never' }],
//'func-style' : ['error', 'expression', { allowArrowFunctions: true }],
'no-array-constructor' : 'error',
'no-iterator' : 'error',
'no-nested-ternary' : 'error',
'no-new-object' : 'error',
'no-proto' : 'error',
'react/jsx-no-bind' : ['error', { allowArrowFunctions: true }],
'react/jsx-uses-react' : 'error',
'react/prefer-es6-class' : ['error', 'never'],
'jest/valid-expect' : ['error', { maxArgs: 3 }],
/** Warnings **/
'max-lines' : ['warn', {
max : 200,
skipComments : true,
skipBlankLines : true,
}],
'max-depth' : ['warn', { max: 4 }],
'max-params' : ['warn', { max: 5 }],
'no-restricted-syntax' : ['warn', 'ClassDeclaration', 'SwitchStatement'],
'no-unused-vars' : ['warn', {
vars : 'all',
args : 'none',
varsIgnorePattern : 'config|_|cx|createClass'
}],
'react/jsx-uses-vars' : 'warn',
/** Fixable **/
'arrow-parens' : ['warn', 'always'],
'brace-style' : ['warn', '1tbs', { allowSingleLine: true }],
'jsx-quotes' : ['warn', 'prefer-single'],
'no-var' : 'warn',
'prefer-const' : 'warn',
'prefer-template' : 'warn',
'quotes' : ['warn', 'single', { 'allowTemplateLiterals': true }],
'semi' : ['warn', 'always'],
/** Whitespace **/
'array-bracket-spacing' : ['warn', 'never'],
'arrow-spacing' : ['warn', { before: false, after: false }],
'comma-spacing' : ['warn', { before: false, after: true }],
'indent' : ['warn', 'tab', { 'MemberExpression': 'off' }],
'keyword-spacing' : ['warn', {
before : true,
after : true,
overrides : {
if : { 'before': false, 'after': false }
}
}],
'key-spacing' : ['warn', {
multiLine : { beforeColon: true, afterColon: true, align: 'colon' },
singleLine : { beforeColon: false, afterColon: true }
}],
'linebreak-style' : 'off',
'no-trailing-spaces' : 'warn',
'no-whitespace-before-property' : 'warn',
'object-curly-spacing' : ['warn', 'always'],
'react/jsx-indent-props' : ['warn', 'tab'],
'space-in-parens' : ['warn', 'never'],
'template-curly-spacing' : ['warn', 'never'],
}
};

4
.gitattributes vendored
View File

@@ -1 +1,3 @@
package-lock.json binary
package-lock.json binary
*.json text eol=lf

36
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,36 @@
<!--
Before submitting a Pull Request, please consider the following to speed up reviews:
- 👷‍♀️ Create small PRs. Large PRs can usually be broken down into incremental PRs.
- 🚩 Do you already have several open PRs? Consider finishing or asking for help with existing PRs first.
- 🔧 Does your PR reference a discussed and approved issue, especially for personal or edge-case requests?
- 💡 Is the solution agreed upon? Save rework time by discussing strategy before coding.
-->
## Description
## Related Issues or Discussions
- Closes #
## QA Instructions, Screenshots, Recordings
_Please replace this line with instructions on how to test or view your changes, as well as any before/after
images for UI changes._
### Reviewer Checklist
_Please replace the list below with specific features you want reviewers to look at._
*Reviewers, refer to this list when testing features, or suggest new items *
- [ ] Verify new features are functional
- [ ] Feature A does X
- [ ] Feature B does Y
- [ ] Verify old features have not broken
- [ ] Feature Z can still be used
- [ ] Test for edge cases / try to break things
- [ ] Feature A handles negative numbers
- [ ] Identify opportunities for simplification and refactoring
- [ ] Check for code legibility and appropriate comments
<details><summary>Copy this list</summary>

View File

@@ -3,7 +3,7 @@
"stylelint-config-recess-order",
"stylelint-config-recommended"],
"plugins": [
"stylelint-stylistic",
"@stylistic/stylelint-plugin",
"./stylelint_plugins/declaration-colon-align.js",
"./stylelint_plugins/declaration-colon-min-space-before",
"./stylelint_plugins/declaration-block-multi-line-min-declarations"
@@ -16,32 +16,32 @@
"font-family-no-missing-generic-family-keyword" : null,
"font-weight-notation" : "named-where-possible",
"font-family-name-quotes" : "always-unless-keyword",
"stylistic/indentation" : "tab",
"@stylistic/indentation" : "tab",
"no-duplicate-selectors" : true,
"stylistic/color-hex-case" : "upper",
"@stylistic/color-hex-case" : "upper",
"color-hex-length" : "long",
"stylistic/selector-combinator-space-after" : "always",
"stylistic/selector-combinator-space-before" : "always",
"stylistic/selector-attribute-operator-space-before" : "never",
"stylistic/selector-attribute-operator-space-after" : "never",
"stylistic/selector-attribute-brackets-space-inside" : "never",
"@stylistic/selector-combinator-space-after" : "always",
"@stylistic/selector-combinator-space-before" : "always",
"@stylistic/selector-attribute-operator-space-before" : "never",
"@stylistic/selector-attribute-operator-space-after" : "never",
"@stylistic/selector-attribute-brackets-space-inside" : "never",
"selector-attribute-quotes" : "always",
"selector-pseudo-element-colon-notation" : "double",
"stylistic/selector-pseudo-class-parentheses-space-inside" : "never",
"stylistic/block-opening-brace-space-before" : "always",
"@stylistic/selector-pseudo-class-parentheses-space-inside" : "never",
"@stylistic/block-opening-brace-space-before" : "always",
"naturalcrit/declaration-colon-min-space-before" : 1,
"stylistic/declaration-block-trailing-semicolon" : "always",
"stylistic/declaration-colon-space-after" : "always",
"stylistic/number-leading-zero" : "always",
"@stylistic/declaration-block-trailing-semicolon" : "always",
"@stylistic/declaration-colon-space-after" : "always",
"@stylistic/number-leading-zero" : "always",
"function-url-quotes" : ["always", { "except": ["empty"] }],
"function-url-scheme-disallowed-list" : ["data","http"],
"comment-whitespace-inside" : "always",
"stylistic/string-quotes" : "single",
"stylistic/media-feature-range-operator-space-before" : "always",
"stylistic/media-feature-range-operator-space-after" : "always",
"stylistic/media-feature-parentheses-space-inside" : "never",
"stylistic/media-feature-colon-space-before" : "always",
"stylistic/media-feature-colon-space-after" : "always",
"@stylistic/string-quotes" : "single",
"@stylistic/media-feature-range-operator-space-before" : "always",
"@stylistic/media-feature-range-operator-space-after" : "always",
"@stylistic/media-feature-parentheses-space-inside" : "never",
"@stylistic/media-feature-colon-space-before" : "always",
"@stylistic/media-feature-colon-space-after" : "always",
"naturalcrit/declaration-colon-align" : true,
"naturalcrit/declaration-block-multi-line-min-declarations": 1
}

View File

@@ -1,4 +1,4 @@
FROM node:18-alpine
FROM node:20-alpine
RUN apk --no-cache add git
ENV NODE_ENV=docker

10
babel.config.json Normal file
View File

@@ -0,0 +1,10 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-transform-runtime",
"babel-plugin-transform-import-meta"
]
}

View File

@@ -81,9 +81,311 @@ pre {
}
```
## changelog
For a full record of development, visit our [Github Page](https://github.com/naturalcrit/homebrewery).
### Wednesday 11/27/2024 - v3.16.1
{{taskList
##### 5e-Cleric
* [x] Allow linking to specific HTML IDs via `#ID` at the end of the URL, e.g.: `homebrewery.naturalcrit.com/share/share/a6RCXwaDS58i#p4` to link to Page 4 directly
Fixes issues [#2820](https://github.com/naturalcrit/homebrewery/issues/2820), [#3505](https://github.com/naturalcrit/homebrewery/issues/3505)
* [x] Fix generation of link to certain Google Drive brews
Fixes issue [#3776](https://github.com/naturalcrit/homebrewery/issues/3776)
##### abquintic
* [x] Fix blank pages appearing when pasting text
Fixes issue [#3718](https://github.com/naturalcrit/homebrewery/issues/3718)
##### Gazook89
* [x] Add new brew viewing options to the view toolbar
- {{fac,single-spread}} {{openSans **SINGLE PAGE**}}
- {{fac,facing-spread}} {{openSans **TWO PAGE**}}
- {{fac,flow-spread}} {{openSans **GRID**}}
Fixes issue [#1379](https://github.com/naturalcrit/homebrewery/issues/1379)
* [x] Updates to tag input boxes
##### G-Ambatte
* [x] Admin tools to fix certain corrupted documents
Fixes issue [#3801](https://github.com/naturalcrit/homebrewery/issues/3801)
* [x] Fix print window being affected by document zoom
Fixes issue [#3744](https://github.com/naturalcrit/homebrewery/issues/3744)
##### calculuschild, 5e-Cleric, G-Ambatte, Gazook89, abquintic
* [x] Multiple code refactors, cleanups, and security fixes
}}
### Saturday 10/12/2024 - v3.16.0
{{taskList
##### 5e-Cleric
* [x] Added a new API endpoint `/metadata/:shareId` to fetch metadata about individual brews
Fixes issue [#2638](https://github.com/naturalcrit/homebrewery/issues/2638)
* [x] Added A3, A5, and Card page size snippets under {{openSans **:fas_paintbrush: STYLE TAB :fas_arrow_right: :fas_print: PRINT**}}
* [x] Adjust navbar styling for very long titles
Fixes issue [#2071](https://github.com/naturalcrit/homebrewery/issues/2071)
* [x] Added some sorting options to the {{openSans **VAULT** {{fas,fa-dungeon}}}} page
* [x] Fix `language` property not working in share page
Fixes issue [#3776](https://github.com/naturalcrit/homebrewery/issues/3776)
##### abquintic
* [x] New {{openSans **:fas_pencil: TEXT EDITOR :fas_arrow_right: :fas_bookmark: PAGE NUMBER :fas_arrow_right:**}}
{{openSans **:fas_xmark: SKIP PAGE NUMBER**}} and {{openSans **:fas_arrow_rotate_left: RESTART PAGE NUMBER**}} snippets for more control over automatic page numbering.
Fixes issue [#513](https://github.com/naturalcrit/homebrewery/issues/513)
* [x] New Table of Contents control options via {{openSans **:fas_pencil: TEXT EDITOR :fas_arrow_right: :fas_book: TABLE OF CONTENTS**}} submenus. By default, H1-H3 is included in the ToC generation, but the new options allow marking `{{blocks}}` to include or exclude specific or ranges of contained headers. Also, a global option to increase the default range of H1-H3 to H1-H4/5/6. After applying these markers, you must regenerate the Table of Contents to see the changes.
* [x] Added a ":fas_lock: SYNC VIEWS" button onto the divider bar. When locked, scrolling on either panel will sync the other panel to the same page.
Fixes issue [#241](https://github.com/naturalcrit/homebrewery/issues/241)
##### Gazook89
* [x] Added a :fas_glasses: HIDE button to the page navigation bar
##### G-Ambatte
* [x] Automatic local backups of your files, in case of accidental data loss. Stores up to 5 snapshots of each brew edited in your browser, incrementing from a few minutes old to a maximum of several days. Restore a backup by clicking an entry in the new {{openSans **:fas_clock_rotate_left: HISTORY**}} button in the snippet bar.
Fixes issue [#3070](https://github.com/naturalcrit/homebrewery/issues/3070)
* [x] Fix issue with legacy brews breaking on Share page
Fixes issue [#3764](https://github.com/naturalcrit/homebrewery/issues/3764)
* [x] Fix print size when printing a zoomed document
Fixes issue [#3744](https://github.com/naturalcrit/homebrewery/issues/3744)
##### All
* [x] Background code cleanup, security fixes, dev tool improvements, dependency updates, prep for upcoming features, etc.
}}
### Wednesday 9/25/2024 - v3.15.1
{{taskList
##### calculuschild
* [x] Background fixes to handle Google Drive issues
* [x] Remove duplicate error logging
##### calculuschild, 5e-Cleric
* [x] Fix links in {{openSans **RECENT BREWS :fas_clock_rotate_left:**}} and user {{openSans **BREWS :fas_beer_mug_empty:**}} pointing to trashed Google Drive files after transferring from Google to Homebrewery storage
Fixes issue [#3776](https://github.com/naturalcrit/homebrewery/issues/3776)
}}
\page
### Wednesday 9/04/2024 - v3.15.0
{{taskList
##### 5e-Cleric, abquintic, calculuschild, Gazook89, G-Ambatte, Ericsheid, Kaiburr
* [x] New {{openSans **VAULT** {{fas,fa-dungeon}}}} page 🎉🎉🎉
:
All **PUBLISHED** brews ({{openSans :fas_circle_info: **Properties**}} menu) will be searchable, by title or author, and filtered by renderer. More features and adjustments will be coming.
:
Note: If any of your own brews are not showing up in search (particularly if stored on Google Drive), please edit and re-save to ensure our database has the data needed from document to be searchable.
Fixes issue [#697](https://github.com/naturalcrit/homebrewery/issues/697)
##### Gazook89
* [x] Auto-focus on text editor when switching editor tabs
}}
### Wednesday 8/28/2024 - v3.14.3
{{taskList
##### calculuschild, G-Ambatte
* [x] New {{openSans **IMAGES → {{fac,image-wrap-left}} IMAGE WRAP LEFT/RIGHT**}} snippets
Fixes issue [#380](https://github.com/naturalcrit/homebrewery/issues/380)
* [x] Fix v3.14.2 bug with `` failing after tables
##### 5e-Cleric
* [x] Fix Account page crash when not logged in
Fixes issue [#3605](https://github.com/naturalcrit/homebrewery/issues/3605)
##### abquintic
* [x] Fix jump hotkeys conflicting with `CTRL + SHIFT`. Preview and Source movement shortcuts now use `CTRL + SHIFT + META + LEFT\RIGHTARROW`
##### G-Ambatte
* [x] Fix display issue with image wrap icons
}}
### Tuesday 8/27/2024 - v3.14.2
{{taskList
##### calculuschild
* [x] Reroute invalid urls to homepage
Fixes issues [#3269](https://github.com/naturalcrit/homebrewery/issues/3629)
* [x] Background dependency updates
##### G-Ambatte
* [x] Add route to get brew styling via `/css/shareId`
Fixes issues [#1097](https://github.com/naturalcrit/homebrewery/issues/1097)
* [x] Fix `:emojis:` preventing code folding
Fixes issues [#3604](https://github.com/naturalcrit/homebrewery/issues/3604)
* [x] Fix mask image warping when rotated and stretched
Fixes issues [#3636](https://github.com/naturalcrit/homebrewery/issues/3636)
* [x] Fix Table of Contents uppercasing
Fixes issues [#3572](https://github.com/naturalcrit/homebrewery/issues/3572)
##### abquintic
* [x] Create globally unique Header IDs across pages
Fixes issues [#1430](https://github.com/naturalcrit/homebrewery/issues/1430)
* [x] Fix colon `` being parsed in codeblocks
* [x] Prevent crashes when loading undefined renderer or theme bundle
* [x] Add Jump-To hotkeys
* Use `CTRL/META + SHIFT + LEFTARROW` to brewJump
* Use `CTRL/META + SHIFT + RIGHTARROW` to sourceJump
* [x] Prevent reload from clobbering modified fresh clones
##### 5e-Cleric, Gazook89
* [x] Viewer tools for zoom/page navigation
}}
### Tuesday 8/13/2024 - v3.14.1
{{taskList
##### abquintic
* [x] Allow Table of Contents to flow across columns
Fixes issues [#2563](https://github.com/naturalcrit/homebrewery/issues/2563)
* [x] Fix unusual margin spacing for adjacent `.descriptive` and `.wide` blocks
Fixes issues [#2688](https://github.com/naturalcrit/homebrewery/issues/2688)
* [x] Add code folding to :fas_paintbrush: {{openSans **STYLE**}} tab
##### G-Ambatte
* [x] Fix edge case where Table of Contents generator changed capitalization of headings
Fixes issues [#3572](https://github.com/naturalcrit/homebrewery/issues/3572)
* [x] Fix **Ink Friendly** snippet causing unselectable PDF text
Fixes issues [#3563](https://github.com/naturalcrit/homebrewery/issues/3563)
* [x] Prevent brews selecting themselves as a theme
Fixes issues [#3614](https://github.com/naturalcrit/homebrewery/issues/3614)
* [x] Fix info pages (`/faq`, `/migrate`, etc.) showing blank authorship info
Fixes issues [#3568](https://github.com/naturalcrit/homebrewery/issues/3568)
* [x] Add `abs()`, `sign()` and `signed()` functions to variable syntax math handler
Fixes issues [#3537](https://github.com/naturalcrit/homebrewery/issues/3537)
* [x] Fix variable math handler not processing commas (i.e., in `$[max(varA,varB)]`
Fixes issues [#3613](https://github.com/naturalcrit/homebrewery/issues/3613)
* [x] Fix variable math handler scrambling variables with names that are subsets of other variables
Fixes issues [#3622](https://github.com/naturalcrit/homebrewery/issues/3622)
##### calculuschild
* [x] Fix `/migrate` page using an editor context instead of share context
##### 5e-Cleric
* [x] Fix Monster Stat Blocks losing color in Safari
}}
\page
### Monday 7/29/2024 - v3.14.0
{{taskList
##### abquintic, calculuschild
* [x] Alternative Brew Themes, including importing other brews as a base theme.
- In the :fas_circle_info: **Properties** menu, find the new {{openSans **THEME**}} dropdown. It lists Brew Themes, including a new **Blank** theme as a simpler basis for custom styling.
- Brews tagged with `meta:theme` will appear in the Brew Themes list. Selecting one loads its :fas_paintbrush: **Style** tab contents as the CSS basis for the current brew, allowing one brew to style multiple documents.
- Brews with `meta:theme` can also select their own Theme, i.e. layering Themes on top of each other.
- The next goal is to make **Published** Themes shareable between users.
Fixes issues [#1899](https://github.com/naturalcrit/homebrewery/issues/1899), [#3085](https://github.com/naturalcrit/homebrewery/issues/3085)
##### G-Ambatte
* [x] Fix Drop-cap font becoming corrupted when Bold
Fixes issues [#3551](https://github.com/naturalcrit/homebrewery/issues/3551)
* [x] Fixes to UI styling
Fixes issues [#3568](https://github.com/naturalcrit/homebrewery/issues/3568)
}}
### Saturday 6/7/2024 - v3.13.1
{{taskList
@@ -131,8 +433,6 @@ Fixes issue [#3298](https://github.com/naturalcrit/homebrewery/issues/3298)
Fixes issue [#3397](https://github.com/naturalcrit/homebrewery/issues/3397)
}}
\column
### Monday 18/3/2024 - v3.12.0
{{taskList
@@ -424,7 +724,7 @@ Fixes issue [#2729](https://github.com/naturalcrit/homebrewery/issues/2729),
### Thursday 17/08/2023 - v3.9.2
{{taskList
##### Calculuschild
##### calculuschild
* [x] Fix links to certain old Google Drive files
@@ -482,7 +782,7 @@ Fixes issue [#1924](https://github.com/naturalcrit/homebrewery/issues/1924)
### Friday 02/06/2023 - v3.9.0
{{taskList
##### Calculuschild
##### calculuschild
* [x] Fix some files not showing up on userpage when user has a large number of brews in Google Drive
@@ -579,7 +879,7 @@ Fixes issues [#2731](https://github.com/naturalcrit/homebrewery/issues/2731)
### Monday 13/03/2023 - v3.7.2
{{taskList
##### Calculuschild
##### calculuschild
* [x] Fix wide Monster Stat Blocks not spanning columns on Legacy
}}
@@ -602,7 +902,7 @@ Fixes issues [#1569](https://github.com/naturalcrit/homebrewery/issues/1569)
* [x] Updated the Google Drive icon
* [x] Backend fix to unit tests failing intermittently
##### Calculuschild
##### calculuschild
* [x] Fix PDF pixelation on CoverPage text outlines
}}
@@ -614,7 +914,7 @@ Fixes issues [#1569](https://github.com/naturalcrit/homebrewery/issues/1569)
**NOTE:** Some new snippets will now show a {{beta BETA}} tag. Feel free to use them, but be aware we may change how they work depending on your feedback.
}}
##### Calculuschild
##### calculuschild
* [x] New {{openSans **IMAGES → WATERCOLOR EDGE** {{fac,mask-edge}} }} and {{openSans **WATERCOLOR CORNER** {{fac,mask-corner}} }} snippets for V3, which adds a stylish watercolor texture to the edge of your images! (Thanks to /u/flamableconcrete on Reddit for providing these image masks!)
@@ -758,7 +1058,7 @@ Fixes issues [#1670](https://github.com/naturalcrit/homebrewery/issues/1670)
### Thursday 28/10/2022 - v3.3.1
{{taskList
##### Calculuschild
##### calculuschild
* [x] Fixes to several broken CSS styles from v3.3.0
@@ -773,7 +1073,7 @@ Fixes issues [#2468](https://github.com/naturalcrit/homebrewery/issues/2468)
### Friday 19/10/2022 - v3.3.0
{{taskList
##### Calculuschild
##### calculuschild
* [x] Fix for tables broken by Chrome v106
@@ -856,7 +1156,7 @@ Fixes issues [#2317](https://github.com/naturalcrit/homebrewery/issues/2317), [
### Wednesday 31/08/2022 - v3.2.1
{{taskList
##### Calculuschild
##### calculuschild
* [x] Reference Links should now work inside tables
@@ -882,7 +1182,7 @@ Fixes issues [#2317](https://github.com/naturalcrit/homebrewery/issues/2317), [
### Saturday 27/08/2022 - v3.2.0
{{taskList
##### Calculuschild
##### calculuschild
* [x] The V3 renderer is now the default for new brews.
@@ -909,7 +1209,7 @@ Fixes issues [#2317](https://github.com/naturalcrit/homebrewery/issues/2317), [
### Thursday 09/06/2022 - v3.1.1
{{taskList
##### Calculuschild:
##### calculuschild:
* [x] Fixed class table decorations appearing on top of the table in PDF output.
@@ -1753,4 +2053,4 @@ Massive changelog incoming:
* Added `phb.standalone.css` plus a build system for creating it
* Added page numbers and footer text
* Page accent now flips each page
* Page accent now flips each page

View File

@@ -2,35 +2,44 @@ require('./admin.less');
const React = require('react');
const createClass = require('create-react-class');
const BrewUtils = require('./brewUtils/brewUtils.jsx');
const NotificationUtils = require('./notificationUtils/notificationUtils.jsx');
const BrewCleanup = require('./brewCleanup/brewCleanup.jsx');
const BrewLookup = require('./brewLookup/brewLookup.jsx');
const BrewCompress = require ('./brewCompress/brewCompress.jsx');
const Stats = require('./stats/stats.jsx');
const tabGroups = ['brew', 'notifications'];
const Admin = createClass({
getDefaultProps : function() {
return {};
},
getInitialState : function(){
return ({
currentTab : 'brew'
});
},
handleClick : function(newTab){
if(this.state.currentTab === newTab) return;
this.setState({
currentTab : newTab
});
},
render : function(){
return <div className='admin'>
<header>
<div className='container'>
<i className='fas fa-rocket' />
homebrewery admin
</div>
</header>
<div className='container'>
<Stats />
<hr />
<BrewLookup />
<hr />
<BrewCleanup />
<hr />
<BrewCompress />
</div>
<main className='container'>
<nav className='tabs'>
{tabGroups.map((tab, idx)=>{ return <button className={tab===this.state.currentTab ? 'active' : ''} key={idx} onClick={()=>{ return this.handleClick(tab); }}>{tab.toUpperCase()}</button>; })}
</nav>
{this.state.currentTab==='brew' && <BrewUtils />}
{this.state.currentTab==='notifications' && <NotificationUtils />}
</main>
</div>;
}
});

View File

@@ -6,39 +6,95 @@
@import 'font-awesome/css/font-awesome.css';
html,body, #reactContainer, .naturalCrit{
min-height : 100%;
}
html,body, #reactContainer, .naturalCrit { min-height : 100%; }
@sidebarWidth : 250px;
body{
background-color : #eee;
font-family : 'Open Sans', sans-serif;
color : #4b5055;
font-weight : 100;
text-rendering : optimizeLegibility;
margin : 0;
body {
height : 100%;
padding : 0;
height : 100%;
margin : 0;
font-family : 'Open Sans', sans-serif;
font-weight : 100;
color : #4B5055;
background-color : #EEEEEE;
text-rendering : optimizeLegibility;
}
.admin{
:where(.admin) {
header{
header {
padding : 20px 0px;
margin-bottom : 30px;
font-size : 2em;
color : white;
background-color : @red;
font-size: 2em;
padding : 20px 0px;
color : white;
margin-bottom: 30px;
i{
margin-right: 30px;
i { margin-right : 30px; }
}
hr { margin : 30px 0px; }
:where(.container) {
input {
height : 33px;
padding : 0px 10px;
margin-bottom : 20px;
font-family : monospace;
}
button {
height : 37px;
vertical-align : middle;
}
dl {
@maxItemWidth : 132px;
dt {
float : left;
width : @maxItemWidth;
clear : left;
text-align : right;
&::after { content : ' : '; }
}
dd {
height : 1em;
padding : 0 0 0.5em 0;
margin-left : @maxItemWidth + 6px;
}
}
.tabs button {
margin-right : 3px;
margin-left : 3px;
color : black;
background-color : #EEEEEE;
border : 1px solid #444444;
border-radius : 5px;
&:hover {
color : #EEEEEE;
background-color : #444444;
}
&.active {
margin-right : 2px;
margin-left : 2px;
text-decoration : underline;
background-color : #CCCCCC;
border : 2px solid #444444;
}
}
.notificationUtils {
display : flex;
gap : 50px;
justify-content : space-between;
}
}
hr{
margin : 30px 0px;
.error {
background: rgb(178, 54, 54);
color:white;
font-weight: 900;
margin-block:10px;
padding:10px;
}
}

View File

@@ -1,10 +0,0 @@
.BrewCleanup{
.removeBox{
margin-top: 20px;
button{
background-color: @red;
margin-right: 10px;
}
}
}

View File

@@ -1,10 +0,0 @@
.BrewCompress{
.removeBox{
margin-top: 20px;
button{
background-color: @red;
margin-right: 10px;
}
}
}

View File

@@ -1,30 +0,0 @@
.brewLookup{
input{
height : 33px;
margin-bottom : 20px;
padding : 0px 10px;
font-family : monospace;
}
button{
vertical-align : middle;
height : 37px;
}
dl{
@maxItemWidth : 132px;
dt{
float : left;
clear : left;
width : @maxItemWidth;
text-align : right;
&::after {
content: " : ";
}
}
dd{
height : 1em;
margin-left : @maxItemWidth + 6px;
padding : 0 0 0.5em 0;
}
}
}

View File

@@ -0,0 +1,9 @@
.BrewCleanup {
.removeBox {
margin-top : 20px;
button {
margin-right : 10px;
background-color : @red;
}
}
}

View File

@@ -0,0 +1,9 @@
.BrewCompress {
.removeBox {
margin-top : 20px;
button {
margin-right : 10px;
background-color : @red;
}
}
}

View File

@@ -1,4 +1,5 @@
require('./brewLookup.less');
const React = require('react');
const createClass = require('create-react-class');
const cx = require('classnames');
@@ -13,22 +14,43 @@ const BrewLookup = createClass({
},
getInitialState() {
return {
query : '',
foundBrew : null,
searching : false,
error : null
query : '',
foundBrew : null,
searching : false,
error : null,
scriptCount : 0
};
},
handleChange(e){
this.setState({ query: e.target.value });
},
lookup(){
this.setState({ searching: true, error: null });
this.setState({ searching: true, error: null, scriptCount: 0 });
request.get(`/admin/lookup/${this.state.query}`)
.then((res)=>this.setState({ foundBrew: res.body }))
.then((res)=>{
const foundBrew = res.body;
const scriptCheck = foundBrew?.text.match(/(<\/?s)cript/g);
this.setState({
foundBrew : foundBrew,
scriptCount : scriptCheck?.length || 0,
});
})
.catch((err)=>this.setState({ error: err }))
.finally(()=>this.setState({ searching: false }));
.finally(()=>{
this.setState({
searching : false
});
});
},
async cleanScript(){
if(!this.state.foundBrew?.shareId) return;
await request.put(`/admin/clean/script/${this.state.foundBrew.shareId}`)
.catch((err)=>{ this.setState({ error: err }); return; });
this.lookup();
},
renderFoundBrew(){
@@ -47,12 +69,23 @@ const BrewLookup = createClass({
<dt>Share Link</dt>
<dd><a href={`/share/${brew.shareId}`} target='_blank' rel='noopener noreferrer'>/share/{brew.shareId}</a></dd>
<dt>Created Time</dt>
<dd>{brew.createdAt ? Moment(brew.createdAt).toLocaleString() : 'No creation date'}</dd>
<dt>Last Updated</dt>
<dd>{Moment(brew.updatedAt).fromNow()}</dd>
<dt>Num of Views</dt>
<dd>{brew.views}</dd>
<dt>SCRIPT tags detected</dt>
<dd>{this.state.scriptCount}</dd>
</dl>
{this.state.scriptCount > 0 &&
<div className='cleanButton'>
<button onClick={this.cleanScript}>CLEAN BREW</button>
</div>
}
</div>;
},

View File

@@ -0,0 +1,6 @@
.brewLookup {
.cleanButton {
display : inline-block;
width : 100%;
}
}

View File

@@ -0,0 +1,24 @@
const React = require('react');
const createClass = require('create-react-class');
const BrewCleanup = require('./brewCleanup/brewCleanup.jsx');
const BrewLookup = require('./brewLookup/brewLookup.jsx');
const BrewCompress = require ('./brewCompress/brewCompress.jsx');
const Stats = require('./stats/stats.jsx');
const BrewUtils = createClass({
render : function(){
return <>
<Stats />
<hr />
<BrewLookup />
<hr />
<BrewCleanup />
<hr />
<BrewCompress />
</>;
}
});
module.exports = BrewUtils;

View File

@@ -0,0 +1,13 @@
.Stats {
position : relative;
.pending {
position : absolute;
top : 0px;
left : 0px;
width : 100%;
height : 100%;
background-color : rgba(238,238,238, 0.5);
}
}

View File

@@ -0,0 +1,109 @@
require('./notificationAdd.less');
const React = require('react');
const { useState, useRef } = require('react');
const request = require('superagent');
const NotificationAdd = ()=>{
const [notificationResult, setNotificationResult] = useState(null);
const [searching, setSearching] = useState(false);
const [error, setError] = useState(null);
const dismissKeyRef = useRef(null);
const titleRef = useRef(null);
const textRef = useRef(null);
const startAtRef = useRef(null);
const stopAtRef = useRef(null);
const saveNotification = async ()=>{
const dismissKey = dismissKeyRef.current.value;
const title = titleRef.current.value;
const text = textRef.current.value;
const startAt = new Date(startAtRef.current.value);
const stopAt = new Date(stopAtRef.current.value);
// Basic validation
if(!dismissKey || !title || !text || isNaN(startAt.getTime()) || isNaN(stopAt.getTime())) {
setError('All fields are required');
return;
}
if(startAt >= stopAt) {
setError('End date must be after the start date!');
return;
}
const data = {
dismissKey,
title,
text,
startAt : startAt?.toISOString() ?? '',
stopAt : stopAt?.toISOString() ?? '',
};
try {
setSearching(true);
setError(null);
const response = await request.post('/admin/notification/add').send(data);
console.log(response.body);
// Reset form fields
dismissKeyRef.current.value = '';
titleRef.current.value = '';
textRef.current.value = '';
setNotificationResult('Notification successfully created.');
setSearching(false);
} catch (err) {
console.log(err.response.body.message);
setError(`Error saving notification: ${err.response.body.message}`);
setSearching(false);
}
};
return (
<div className='notificationAdd'>
<h2>Add Notification</h2>
<label className='field'>
Dismiss Key:
<input className='fieldInput' type='text' ref={dismissKeyRef} required
placeholder='dismiss_notif_drive'
/>
</label>
<label className='field'>
Title:
<input className='fieldInput' type='text' ref={titleRef} required
placeholder='Stop using Google Drive as image host'
/>
</label>
<label className='field'>
Text:
<textarea className='fieldInput' type='text' ref={textRef} required
placeholder='Google Drive is not an image hosting site, you should not use it as such.'
>
</textarea>
</label>
<label className='field'>
Start Date:
<input type='date' className='fieldInput' ref={startAtRef} required/>
</label>
<label className='field'>
End Date:
<input type='date' className='fieldInput' ref={stopAtRef} required/>
</label>
<div className='notificationResult'>{notificationResult}</div>
<button className='notificationSave' onClick={saveNotification} disabled={searching}>
<i className={`fas ${searching ? 'fa-spin fa-spinner' : 'fa-save'}`}/>
Save Notification
</button>
{error && <div className='error'>{error}</div>}
</div>
);
};
module.exports = NotificationAdd;

View File

@@ -0,0 +1,37 @@
.notificationAdd {
position : relative;
display : flex;
flex-direction : column;
width : 500px;
.field {
display : grid;
grid-template-columns : 120px 150px;
align-items : center;
justify-items : stretch;
width : 100%;
margin-bottom : 20px;
input {
height : 33px;
padding : 0px 10px;
margin-bottom : unset;
font-family : monospace;
}
textarea {
width : 50ch;
min-height : 7em;
max-height : 20em;
resize : vertical;
padding : 10px;
}
}
button {
width: 200px;
i { margin-right : 10px; }
}
}

View File

@@ -0,0 +1,105 @@
require('./notificationLookup.less');
const React = require('react');
const { useState } = require('react');
const request = require('superagent');
const Moment = require('moment');
const NotificationDetail = ({ notification, onDelete })=>(
<>
<dl>
<dt>Key</dt>
<dd>{notification.dismissKey}</dd>
<dt>Title</dt>
<dd>{notification.title || 'No Title'}</dd>
<dt>Created</dt>
<dd>{Moment(notification.createdAt).format('LLLL')}</dd>
<dt>Start</dt>
<dd>{Moment(notification.startAt).format('LLLL') || 'No Start Time'}</dd>
<dt>Stop</dt>
<dd>{Moment(notification.stopAt).format('LLLL') || 'No End Time'}</dd>
<dt>Text</dt>
<dd>{notification.text || 'No Text'}</dd>
</dl>
<button onClick={()=>onDelete(notification.dismissKey)}>DELETE</button>
</>
);
const NotificationLookup = ()=>{
const [searching, setSearching] = useState(false);
const [error, setError] = useState(null);
const [notifications, setNotifications] = useState([]);
const lookupAll = async ()=>{
setSearching(true);
setError(null);
try {
const res = await request.get('/admin/notification/all');
setNotifications(res.body || []);
} catch (err) {
console.log(err);
setError(`Error looking up notifications: ${err.response.body.message}`);
} finally {
setSearching(false);
}
};
const deleteNotification = async (dismissKey)=>{
if(!dismissKey) return;
const confirmed = window.confirm(
`Really delete notification ${dismissKey}?`
);
if(!confirmed) {
console.log('Delete notification cancelled');
return;
}
console.log('Delete notification confirm');
try {
await request.delete(`/admin/notification/delete/${dismissKey}`);
lookupAll();
} catch (err) {
console.log(err);
setError(`Error deleting notification: ${err.response.body.message}`);
};
};
const renderNotificationsList = ()=>{
if(error)
return <div className='error'>{error}</div>;
if(notifications.length === 0)
return <div className='noNotification'>No notifications available.</div>;
return (
<ul className='notificationList'>
{notifications.map((notification)=>(
<li key={notification.dismissKey} >
<details>
<summary>{notification.title || 'No Title'}</summary>
<NotificationDetail notification={notification} onDelete={deleteNotification} />
</details>
</li>
))}
</ul>
);
};
return (
<div className='notificationLookup'>
<h2>Check all Notifications</h2>
<button onClick={lookupAll}>
<i className={`fas ${searching ? 'fa-spin fa-spinner' : 'fa-search'}`} />
</button>
{renderNotificationsList()}
</div>
);
};
module.exports = NotificationLookup;

View File

@@ -0,0 +1,40 @@
.notificationLookup {
width : 450px;
height : fit-content;
.notificationList {
display : flex;
flex-direction : column;
max-height : 500px;
margin-block : 20px;
overflow : auto;
border : 1px solid;
border-radius : 5px;
li {
padding : 10px;
background : #CCCCCC;
&:nth-child(even) { background : #DDDDDD; }
&:first-child {
border-top-left-radius : 5px;
border-top-right-radius : 5px;
}
&:last-child {
border-bottom-right-radius : 5px;
border-bottom-left-radius : 5px;
}
summary {
font-size : 20px;
font-weight : 900;
}
dl dt{
font-weight: 900;
}
}
}
.noNotification { margin-block : 20px; }
}

View File

@@ -0,0 +1,15 @@
const React = require('react');
const NotificationLookup = require('./notificationLookup/notificationLookup.jsx');
const NotificationAdd = require('./notificationAdd/notificationAdd.jsx');
const NotificationUtils = ()=>{
return (
<section className='notificationUtils'>
<NotificationAdd />
<NotificationLookup />
</section>
);
};
module.exports = NotificationUtils;

View File

@@ -1,28 +0,0 @@
.Stats{
position : relative;
.pending{
position : absolute;
top : 0px;
left : 0px;
height : 100%;
width : 100%;
background-color : rgba(238,238,238, 0.5);
}
dl{
@maxItemWidth : 132px;
dt{
float : left;
clear : left;
width : @maxItemWidth;
text-align : right;
&::after {
content: " : ";
}
}
dd{
margin : 0 0 0 @maxItemWidth + 10px;
padding : 0 0 0.5em 0;
}
}
}

View File

@@ -0,0 +1,91 @@
import React, { useState, useRef, forwardRef, useEffect, cloneElement, Children } from 'react';
import './Anchored.less';
// Anchored is a wrapper component that must have as children an <AnchoredTrigger> and a <AnchoredBox> component.
// AnchoredTrigger must have a unique `id` prop, which is passed up to Anchored, saved in state on mount, and
// then passed down through props into AnchoredBox. The `id` is used for the CSS Anchor Positioning properties.
// **The Anchor Positioning API is not available in Firefox yet**
// So in Firefox the positioning isn't perfect but is likely sufficient, and FF team seems to be working on the API quickly.
const Anchored = ({ children })=>{
const [visible, setVisible] = useState(false);
const [anchorId, setAnchorId] = useState(null);
const boxRef = useRef(null);
const triggerRef = useRef(null);
// promote trigger id to Anchored id (to pass it back down to the box as "anchorId")
useEffect(()=>{
if(triggerRef.current){
setAnchorId(triggerRef.current.id);
}
}, []);
// close box on outside click or Escape key
useEffect(()=>{
const handleClickOutside = (evt)=>{
if(
boxRef.current &&
!boxRef.current.contains(evt.target) &&
triggerRef.current &&
!triggerRef.current.contains(evt.target)
) {
setVisible(false);
}
};
const handleEscapeKey = (evt)=>{
if(evt.key === 'Escape') setVisible(false);
};
window.addEventListener('click', handleClickOutside);
window.addEventListener('keydown', handleEscapeKey);
return ()=>{
window.removeEventListener('click', handleClickOutside);
window.removeEventListener('keydown', handleEscapeKey);
};
}, []);
const toggleVisibility = ()=>setVisible((prev)=>!prev);
// Map children to inject necessary props
const mappedChildren = Children.map(children, (child)=>{
if(child.type === AnchoredTrigger) {
return cloneElement(child, { ref: triggerRef, toggleVisibility, visible });
}
if(child.type === AnchoredBox) {
return cloneElement(child, { ref: boxRef, visible, anchorId });
}
return child;
});
return <>{mappedChildren}</>;
};
// forward ref for AnchoredTrigger
const AnchoredTrigger = forwardRef(({ toggleVisibility, visible, children, className, ...props }, ref)=>(
<button
ref={ref}
className={`anchored-trigger${visible ? ' active' : ''} ${className}`}
onClick={toggleVisibility}
style={{ anchorName: `--${props.id}` }} // setting anchor properties here allows greater recyclability.
{...props}
>
{children}
</button>
));
// forward ref for AnchoredBox
const AnchoredBox = forwardRef(({ visible, children, className, anchorId, ...props }, ref)=>(
<div
ref={ref}
className={`anchored-box${visible ? ' active' : ''} ${className}`}
style={{ positionAnchor: `--${anchorId}` }} // setting anchor properties here allows greater recyclability.
{...props}
>
{children}
</div>
));
export { Anchored, AnchoredTrigger, AnchoredBox };

View File

@@ -0,0 +1,13 @@
.anchored-box {
position:absolute;
@supports (inset-block-start: anchor(bottom)){
inset-block-start: anchor(bottom);
}
justify-self: anchor-center;
visibility: hidden;
&.active {
visibility: visible;
}
}

View File

@@ -1,22 +1,26 @@
// Dialog box, for popups and modal blocking messages
const React = require('react');
import React from 'react';
const { useRef, useEffect } = React;
function Dialog({ dismissKey, closeText = 'Close', blocking = false, ...rest }) {
function Dialog({ dismisskeys = [], closeText = 'Close', blocking = false, ...rest }) {
const dialogRef = useRef(null);
useEffect(()=>{
if(!dismissKey || !localStorage.getItem(dismissKey)) {
if(dismisskeys.length !== 0) {
blocking ? dialogRef.current?.showModal() : dialogRef.current?.show();
}
}, []);
}, [dialogRef.current, dismisskeys]);
const dismiss = ()=>{
dismissKey && localStorage.setItem(dismissKey, true);
dismisskeys.forEach((key)=>{
if(key) {
localStorage.setItem(key, 'true');
}
});
dialogRef.current?.close();
};
return (
return (
<dialog ref={dialogRef} onCancel={dismiss} {...rest}>
{rest.children}
<button className='dismiss' onClick={dismiss}>

View File

@@ -1,12 +1,13 @@
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
require('./brewRenderer.less');
const React = require('react');
const { useState, useRef, useEffect } = React;
const { useState, useRef, useCallback, useMemo } = React;
const _ = require('lodash');
const MarkdownLegacy = require('naturalcrit/markdownLegacy.js');
const Markdown = require('naturalcrit/markdown.js');
import Markdown from 'naturalcrit/markdown.js';
const ErrorBar = require('./errorBar/errorBar.jsx');
const ToolBar = require('./toolBar/toolBar.jsx');
//TODO: move to the brew renderer
const RenderWarnings = require('homebrewery/renderWarnings/renderWarnings.jsx');
@@ -15,10 +16,7 @@ const Frame = require('react-frame-component').default;
const dedent = require('dedent-tabs').default;
const { printCurrentBrew } = require('../../../shared/helpers.js');
const DOMPurify = require('dompurify');
const purifyConfig = { FORCE_BODY: true, SANITIZE_DOM: false };
const Themes = require('themes/themes.json');
import { safeHTML } from './safeHTML.js';
const PAGE_HEIGHT = 1056;
@@ -30,6 +28,7 @@ const INITIAL_CONTENT = dedent`
<base target=_blank>
</head><body style='overflow: hidden'><div></div></body></html>`;
//v=====----------------------< Brew Page Component >---------------------=====v//
const BrewPage = (props)=>{
props = {
@@ -37,34 +36,43 @@ const BrewPage = (props)=>{
index : 0,
...props
};
const cleanText = props.contents; //DOMPurify.sanitize(props.contents, purifyConfig);
return <div className={props.className} id={`p${props.index + 1}`} >
const cleanText = safeHTML(props.contents);
return <div className={props.className} id={`p${props.index + 1}`} style={props.style}>
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: cleanText }} />
</div>;
};
//v=====--------------------< Brew Renderer Component >-------------------=====v//
const renderedPages = [];
let renderedPages = [];
let rawPages = [];
const BrewRenderer = (props)=>{
props = {
text : '',
style : '',
renderer : 'legacy',
theme : '5ePHB',
lang : '',
errors : [],
currentEditorPage : 0,
text : '',
style : '',
renderer : 'legacy',
theme : '5ePHB',
lang : '',
errors : [],
currentEditorCursorPageNum : 1,
currentEditorViewPageNum : 1,
currentBrewRendererPageNum : 1,
themeBundle : {},
onPageChange : ()=>{},
...props
};
const [state, setState] = useState({
viewablePageNumber : 0,
height : PAGE_HEIGHT,
isMounted : false,
visibility : 'hidden',
isMounted : false,
visibility : 'hidden'
});
const [displayOptions, setDisplayOptions] = useState({
zoomLevel : 100,
spread : 'single',
startOnRight : true,
pageShadows : true
});
const mainRef = useRef(null);
@@ -75,49 +83,47 @@ const BrewRenderer = (props)=>{
rawPages = props.text.split(/^\\page$/gm);
}
useEffect(()=>{ // Unmounting steps
return ()=>{window.removeEventListener('resize', updateSize);};
}, []);
const scrollToHash = (hash)=>{
if(!hash) return;
const updateSize = ()=>{
setState((prevState)=>({
...prevState,
height : mainRef.current.parentNode.clientHeight,
}));
const iframeDoc = document.getElementById('BrewRenderer').contentDocument;
let anchor = iframeDoc.querySelector(hash);
if(anchor) {
anchor.scrollIntoView({ behavior: 'smooth' });
} else {
// Use MutationObserver to wait for the element if it's not immediately available
new MutationObserver((mutations, obs)=>{
anchor = iframeDoc.querySelector(hash);
if(anchor) {
anchor.scrollIntoView({ behavior: 'smooth' });
obs.disconnect();
}
}).observe(iframeDoc, { childList: true, subtree: true });
}
};
const handleScroll = (e)=>{
const target = e.target;
setState((prevState)=>({
...prevState,
viewablePageNumber : Math.floor(target.scrollTop / target.scrollHeight * rawPages.length)
}));
};
const updateCurrentPage = useCallback(_.throttle((e)=>{
const { scrollTop, clientHeight, scrollHeight } = e.target;
const totalScrollableHeight = scrollHeight - clientHeight;
const currentPageNumber = Math.max(Math.ceil((scrollTop / totalScrollableHeight) * rawPages.length), 1);
props.onPageChange(currentPageNumber);
}, 200), []);
const isInView = (index)=>{
if(!state.isMounted)
return false;
if(index == props.currentEditorPage) //Already rendered before this step
if(index == props.currentEditorCursorPageNum - 1) //Already rendered before this step
return false;
if(Math.abs(index - state.viewablePageNumber) <= 3)
if(Math.abs(index - props.currentBrewRendererPageNum - 1) <= 3)
return true;
return false;
};
const renderPageInfo = ()=>{
return <div className='pageInfo' ref={mainRef}>
<div>
{props.renderer}
</div>
<div>
{state.viewablePageNumber + 1} / {rawPages.length}
</div>
</div>;
};
const renderDummyPage = (index)=>{
return <div className='phb page' id={`p${index + 1}`} key={index}>
<i className='fas fa-spinner fa-spin' />
@@ -125,10 +131,9 @@ const BrewRenderer = (props)=>{
};
const renderStyle = ()=>{
if(!props.style) return;
const cleanStyle = props.style; //DOMPurify.sanitize(props.style, purifyConfig);
//return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style>@layer styleTab {\n${sanitizeScriptTags(props.style)}\n} </style>` }} />;
return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style> ${cleanStyle} </style>` }} />;
const themeStyles = props.themeBundle?.joinedStyles ?? '<style>@import url("/themes/V3/Blank/style.css");</style>';
const cleanStyle = safeHTML(`${themeStyles} \n\n <style> ${props.style} </style>`);
return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: cleanStyle }} />;
};
const renderPage = (pageText, index)=>{
@@ -138,7 +143,13 @@ const BrewRenderer = (props)=>{
} else {
pageText += `\n\n&nbsp;\n\\column\n&nbsp;`; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
const html = Markdown.render(pageText, index);
return <BrewPage className='page' index={index} key={index} contents={html} />;
const styles = {
...(!displayOptions.pageShadows ? { boxShadow: 'none' } : {})
// Add more conditions as needed
};
return <BrewPage className='page' index={index} key={index} contents={html} style={styles} />;
}
};
@@ -150,7 +161,8 @@ const BrewRenderer = (props)=>{
renderedPages.length = 0;
// Render currently-edited page first so cross-page effects (variables, links) can propagate out first
renderedPages[props.currentEditorPage] = renderPage(rawPages[props.currentEditorPage], props.currentEditorPage);
if(rawPages.length > props.currentEditorCursorPageNum -1)
renderedPages[props.currentEditorCursorPageNum - 1] = renderPage(rawPages[props.currentEditorCursorPageNum - 1], props.currentEditorCursorPageNum - 1);
_.forEach(rawPages, (page, index)=>{
if((isInView(index) || !renderedPages[index]) && typeof window !== 'undefined'){
@@ -171,9 +183,9 @@ const BrewRenderer = (props)=>{
};
const frameDidMount = ()=>{ //This triggers when iFrame finishes internal "componentDidMount"
scrollToHash(window.location.hash);
setTimeout(()=>{ //We still see a flicker where the style isn't applied yet, so wait 100ms before showing iFrame
updateSize();
window.addEventListener('resize', updateSize);
renderPages(); //Make sure page is renderable before showing
setState((prevState)=>({
...prevState,
@@ -188,15 +200,30 @@ const BrewRenderer = (props)=>{
document.dispatchEvent(new MouseEvent('click'));
};
const rendererPath = props.renderer == 'V3' ? 'V3' : 'Legacy';
const themePath = props.theme ?? '5ePHB';
const baseThemePath = Themes[rendererPath][themePath].baseTheme;
const handleDisplayOptionsChange = (newDisplayOptions)=>{
setDisplayOptions(newDisplayOptions);
};
const pagesStyle = {
zoom : `${displayOptions.zoomLevel}%`,
columnGap : `${displayOptions.columnGap}px`,
rowGap : `${displayOptions.rowGap}px`
};
const styleObject = {};
if(global.config.deployment) {
styleObject.backgroundImage = `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='40px' width='200px'><text x='0' y='15' fill='%23fff7' font-size='20'>${global.config.deployment}</text></svg>")`;
}
const renderedStyle = useMemo(()=>renderStyle(), [props.style, props.themeBundle]);
renderedPages = useMemo(()=>renderPages(), [displayOptions.pageShadows, props.text]);
return (
<>
{/*render dummy page while iFrame is mounting.*/}
{!state.isMounted
? <div className='brewRenderer' onScroll={handleScroll}>
? <div className='brewRenderer' onScroll={updateCurrentPage}>
<div className='pages'>
{renderDummyPage(1)}
</div>
@@ -204,42 +231,38 @@ const BrewRenderer = (props)=>{
: null}
<ErrorBar errors={props.errors} />
<div className='popups'>
<div className='popups' ref={mainRef}>
<RenderWarnings />
<NotificationPopup />
</div>
<ToolBar displayOptions={displayOptions} currentPage={props.currentBrewRendererPageNum} totalPages={rawPages.length} onDisplayOptionsChange={handleDisplayOptionsChange} />
{/*render in iFrame so broken code doesn't crash the site.*/}
<Frame id='BrewRenderer' initialContent={INITIAL_CONTENT}
style={{ width: '100%', height: '100%', visibility: state.visibility }}
contentDidMount={frameDidMount}
onClick={()=>{emitClick();}}
>
<div className={'brewRenderer'}
onScroll={handleScroll}
<div className={`brewRenderer ${global.config.deployment && 'deployment'}`}
onScroll={updateCurrentPage}
onKeyDown={handleControlKeys}
tabIndex={-1}
style={{ height: state.height }}>
<link href={`/themes/${rendererPath}/Blank/style.css`} type='text/css' rel='stylesheet'/>
{baseThemePath &&
<link href={`/themes/${rendererPath}/${baseThemePath}/style.css`} type='text/css' rel='stylesheet'/>
}
<link href={`/themes/${rendererPath}/${themePath}/style.css`} type='text/css' rel='stylesheet'/>
style={ styleObject }>
{/* Apply CSS from Style tab and render pages from Markdown tab */}
{state.isMounted
&&
<>
{renderStyle()}
<div className='pages' lang={`${props.lang || 'en'}`}>
{renderPages()}
{renderedStyle}
<div lang={`${props.lang || 'en'}`} style={pagesStyle} className={
`pages ${displayOptions.startOnRight ? 'recto' : 'verso'} ${displayOptions.spread}` } >
{renderedPages}
</div>
</>
}
</div>
</Frame>
{renderPageInfo()}
</>
);
};

View File

@@ -1,10 +1,47 @@
@import (multiple, less) 'shared/naturalcrit/styles/reset.less';
.brewRenderer {
will-change : transform;
overflow-y : scroll;
overflow-y : scroll;
will-change : transform;
padding-top : 60px;
height : 100vh;
&:has(.facing, .flow) {
padding : 60px 30px;
}
&.deployment {
background-color: darkred;
}
:where(.pages) {
margin : 30px 0px;
&.facing {
display: grid;
grid-template-columns: repeat(2, auto);
grid-template-rows: repeat(3, auto);
gap: 10px 10px;
justify-content: center;
&.recto .page:first-child {
// sets first page on 'right' ('recto') of the preview, as if for a Cover page.
// todo: add a checkbox to toggle this setting
grid-column-start: 2;
}
& :where(.page) {
margin-left: unset !important;
margin-right: unset !important;
}
}
&.flow {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: flex-start;
& :where(.page) {
flex: 0 0 auto;
margin-left: unset !important;
margin-right: unset !important;
}
}
& > :where(.page) {
width : 215.9mm;
height : 279.4mm;
@@ -13,67 +50,36 @@
margin-left : auto;
box-shadow : 1px 4px 14px #000000;
}
*[id] {
scroll-margin-top:100px;
}
}
&::-webkit-scrollbar {
width: 20px;
&:horizontal{
height: 20px;
width:auto;
width : 20px;
&:horizontal {
width : auto;
height : 20px;
}
&-thumb {
background: linear-gradient(90deg, #d3c1af 15px, #00000000 15px);
&:horizontal{
background: linear-gradient(0deg, #d3c1af 15px, #00000000 15px);
}
}
&-corner {
visibility: hidden;
background : linear-gradient(90deg, #D3C1AF 15px, #00000000 15px);
&:horizontal { background : linear-gradient(0deg, #D3C1AF 15px, #00000000 15px); }
}
&-corner { visibility : hidden; }
}
}
.pane { position : relative; }
.pageInfo {
position : absolute;
right : 17px;
bottom : 0;
z-index : 1000;
font-size : 10px;
font-weight : 800;
color : white;
background-color : #333333;
div {
display : inline-block;
padding : 8px 10px;
&:not(:last-child) { border-right : 1px solid #666666; }
}
}
.ppr_msg {
position : absolute;
bottom : 0;
left : 0px;
z-index : 1000;
padding : 8px 10px;
font-size : 10px;
font-weight : 800;
color : white;
background-color : #333333;
}
@media print {
.toolBar { display : none; }
.brewRenderer {
height: 100%;
overflow-y: unset;
height : 100%;
padding-top : unset;
overflow-y : unset;
.pages {
margin: 0px;
&>.page {
box-shadow: unset;
}
margin : 0px;
zoom: 100% !important;
& > .page { box-shadow : unset; }
}
}
}

View File

@@ -1,43 +1,62 @@
require('./notificationPopup.less');
const React = require('react');
const _ = require('lodash');
import React, { useEffect, useState } from 'react';
import request from '../../utils/request-middleware.js';
import Dialog from '../../../components/dialog.jsx';
const DISMISS_KEY = 'dismiss_notification12-04-23';
const DISMISS_BUTTON = <i className='fas fa-times dismiss' />;
const NotificationPopup = ()=>{
return <Dialog className='notificationPopup' dismissKey={DISMISS_KEY} closeText={DISMISS_BUTTON} >
const [notifications, setNotifications] = useState([]);
const [dissmissKeyList, setDismissKeyList] = useState([]);
const [error, setError] = useState(null);
useEffect(()=>{
getNotifications();
}, []);
const getNotifications = async ()=>{
setError(null);
try {
const res = await request.get('/admin/notification/all');
pickActiveNotifications(res.body || []);
} catch (err) {
console.log(err);
setError(`Error looking up notifications: ${err?.response?.body?.message || err.message}`);
}
};
const pickActiveNotifications = (notifs)=>{
const now = new Date();
const filteredNotifications = notifs.filter((notification)=>{
const startDate = new Date(notification.startAt);
const stopDate = new Date(notification.stopAt);
const dismissed = localStorage.getItem(notification.dismissKey) ? true : false;
return now >= startDate && now <= stopDate && !dismissed;
});
setNotifications(filteredNotifications);
setDismissKeyList(filteredNotifications.map((notif)=>notif.dismissKey));
};
const renderNotificationsList = ()=>{
if(error) return <div className='error'>{error}</div>;
return notifications.map((notification)=>(
<li key={notification.dismissKey} >
<em>{notification.title}</em><br />
<p dangerouslySetInnerHTML={{ __html: notification.text }}></p>
</li>
));
};
return <Dialog className='notificationPopup' dismisskeys={dissmissKeyList} closeText={DISMISS_BUTTON} >
<div className='header'>
<i className='fas fa-info-circle info'></i>
<h3>Notice</h3>
<small>This website is always improving and we are still adding new features and squashing bugs. Keep the following in mind:</small>
</div>
<ul>
<li key='psa'>
<em>Don't store IMAGES in Google Drive</em><br />
Google Drive is not an image service, and will block images from being used
in brews if they get more views than expected. Google has confirmed they won't fix
this, so we recommend you look for another image hosting service such as imgur, ImgBB or Google Photos.
</li>
<li key='googleDriveFolder'>
<em>Don't delete your Homebrewery folder on Google Drive!</em> <br />
We have had several reports of users losing their brews, not realizing
that they had deleted the files on their Google Drive. If you have a Homebrewery folder
on your Google Drive with *.txt files inside, <em>do not delete it</em>!
We cannot help you recover files that you have deleted from your own
Google Drive.
</li>
<li key='faq'>
<em>Protect your work! </em> <br />
If you opt not to use your Google Drive, keep in mind that we do not save a history of your projects. Please make frequent backups of your brews!&nbsp;
<a target='_blank' href='https://www.reddit.com/r/homebrewery/comments/adh6lh/faqs_psas_announcements/'>
See the FAQ
</a> to learn how to avoid losing your work!
</li>
{renderNotificationsList()}
</ul>
</Dialog>;
};

View File

@@ -1,9 +1,10 @@
.popups {
position : fixed;
top : @navbarHeight;
top : calc(@navbarHeight + @viewerToolsHeight);
right : 24px;
z-index : 10001;
width : 450px;
margin-top : 5px;
}
.notificationPopup {
@@ -54,7 +55,10 @@
margin-top : 1.4em;
font-size : 0.8em;
line-height : 1.4em;
em { font-weight : 800; }
em {
text-transform:capitalize;
font-weight : 800;
}
}
}
}

View File

@@ -0,0 +1,46 @@
// Derived from the vue-html-secure package, customized for Homebrewery
let doc = null;
let div = null;
function safeHTML(htmlString) {
// If the Document interface doesn't exist, exit
if(typeof document == 'undefined') return null;
// If the test document and div don't exist, create them
if(!doc) doc = document.implementation.createHTMLDocument('');
if(!div) div = doc.createElement('div');
// Set the test div contents to the evaluation string
div.innerHTML = htmlString;
// Grab all nodes from the test div
const elements = div.querySelectorAll('*');
// Blacklisted tags
const blacklistTags = ['script', 'noscript', 'noembed'];
// Tests to remove attributes
const blacklistAttrs = [
(test)=>{return test.localName.indexOf('on') == 0;},
(test)=>{return test.localName.indexOf('type') == 0 && test.value.match(/submit/i);},
(test)=>{return test.value.replace(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g, '').toLowerCase().trim().indexOf('javascript:') == 0;}
];
elements.forEach((element)=>{
// Check each element for blacklisted type
if(blacklistTags.includes(element?.localName?.toLowerCase())) {
element.remove();
return;
}
// Check remaining elements for blacklisted attributes
for (const attribute of element.attributes){
if(blacklistAttrs.some((test)=>{return test(attribute);})) {
element.removeAttribute(attribute.localName);
break;
};
};
});
return div.innerHTML;
};
module.exports.safeHTML = safeHTML;

View File

@@ -0,0 +1,227 @@
require('./toolBar.less');
const React = require('react');
const { useState, useEffect } = React;
const _ = require('lodash');
import { Anchored, AnchoredBox, AnchoredTrigger } from '../../../components/Anchored.jsx';
// import * as ZoomIcons from '../../../icons/icon-components/zoomIcons.jsx';
const MAX_ZOOM = 300;
const MIN_ZOOM = 10;
const ToolBar = ({ displayOptions, currentPage, totalPages, onDisplayOptionsChange })=>{
const [pageNum, setPageNum] = useState(currentPage);
const [toolsVisible, setToolsVisible] = useState(true);
useEffect(()=>{
setPageNum(currentPage);
}, [currentPage]);
const handleZoomButton = (zoom)=>{
handleOptionChange('zoomLevel', _.round(_.clamp(zoom, MIN_ZOOM, MAX_ZOOM)));
};
const handleOptionChange = (optionKey, newValue)=>{
//setDisplayOptions(prevOptions => ({ ...prevOptions, [optionKey]: newValue }));
onDisplayOptionsChange({ ...displayOptions, [optionKey]: newValue });
};
const handlePageInput = (pageInput)=>{
if(/[0-9]/.test(pageInput))
setPageNum(parseInt(pageInput)); // input type is 'text', so `page` comes in as a string, not number.
};
const scrollToPage = (pageNumber)=>{
pageNumber = _.clamp(pageNumber, 1, totalPages);
const iframe = document.getElementById('BrewRenderer');
const brewRenderer = iframe?.contentWindow?.document.querySelector('.brewRenderer');
const page = brewRenderer?.querySelector(`#p${pageNumber}`);
page?.scrollIntoView({ block: 'start' });
setPageNum(pageNumber);
};
const calculateChange = (mode)=>{
const iframe = document.getElementById('BrewRenderer');
const iframeWidth = iframe.getBoundingClientRect().width;
const iframeHeight = iframe.getBoundingClientRect().height;
const pages = iframe.contentWindow.document.getElementsByClassName('page');
let desiredZoom = 0;
if(mode == 'fill'){
// find widest page, in case pages are different widths, so that the zoom is adapted to not cut the widest page off screen.
const widestPage = _.maxBy([...pages], 'offsetWidth').offsetWidth;
desiredZoom = (iframeWidth / widestPage) * 100;
} else if(mode == 'fit'){
// find the page with the largest single dim (height or width) so that zoom can be adapted to fit it.
const minDimRatio = [...pages].reduce((minRatio, page)=>Math.min(minRatio, iframeWidth / page.offsetWidth, iframeHeight / page.offsetHeight), Infinity);
desiredZoom = minDimRatio * 100;
}
const margin = 5; // extra space so page isn't edge to edge (not truly "to fill")
const deltaZoom = (desiredZoom - displayOptions.zoomLevel) - margin;
return deltaZoom;
};
return (
<div id='preview-toolbar' className={`toolBar ${toolsVisible ? 'visible' : 'hidden'}`} role='toolbar'>
<button className='toggleButton' title={`${toolsVisible ? 'Hide' : 'Show'} Preview Toolbar`} onClick={()=>{setToolsVisible(!toolsVisible);}}><i className='fas fa-glasses' /></button>
{/*v=====----------------------< Zoom Controls >---------------------=====v*/}
<div className='group' role='group' aria-label='Zoom' aria-hidden={!toolsVisible}>
<button
id='fill-width'
className='tool'
title='Set zoom to fill preview with one page'
onClick={()=>handleZoomButton(displayOptions.zoomLevel + calculateChange('fill'))}
>
<i className='fac fit-width' />
</button>
<button
id='zoom-to-fit'
className='tool'
title='Set zoom to fit entire page in preview'
onClick={()=>handleZoomButton(displayOptions.zoomLevel + calculateChange('fit'))}
>
<i className='fac zoom-to-fit' />
</button>
<button
id='zoom-out'
className='tool'
onClick={()=>handleZoomButton(displayOptions.zoomLevel - 20)}
disabled={displayOptions.zoomLevel <= MIN_ZOOM}
title='Zoom Out'
>
<i className='fas fa-magnifying-glass-minus' />
</button>
<input
id='zoom-slider'
className='range-input tool hover-tooltip'
type='range'
name='zoom'
title='Set Zoom'
list='zoomLevels'
min={MIN_ZOOM}
max={MAX_ZOOM}
step='1'
value={displayOptions.zoomLevel}
onChange={(e)=>handleZoomButton(parseInt(e.target.value))}
/>
<datalist id='zoomLevels'>
<option value='100' />
</datalist>
<button
id='zoom-in'
className='tool'
onClick={()=>handleZoomButton(displayOptions.zoomLevel + 20)}
disabled={displayOptions.zoomLevel >= MAX_ZOOM}
title='Zoom In'
>
<i className='fas fa-magnifying-glass-plus' />
</button>
</div>
{/*v=====----------------------< Spread Controls >---------------------=====v*/}
<div className='group' role='group' aria-label='Spread' aria-hidden={!toolsVisible}>
<div className='radio-group' role='radiogroup'>
<button role='radio'
id='single-spread'
className='tool'
title='Single Page'
onClick={()=>{handleOptionChange('spread', 'active');}}
aria-checked={displayOptions.spread === 'single'}
><i className='fac single-spread' /></button>
<button role='radio'
id='facing-spread'
className='tool'
title='Facing Pages'
onClick={()=>{handleOptionChange('spread', 'facing');}}
aria-checked={displayOptions.spread === 'facing'}
><i className='fac facing-spread' /></button>
<button role='radio'
id='flow-spread'
className='tool'
title='Flow Pages'
onClick={()=>{handleOptionChange('spread', 'flow');}}
aria-checked={displayOptions.spread === 'flow'}
><i className='fac flow-spread' /></button>
</div>
<Anchored>
<AnchoredTrigger id='spread-settings' className='tool' title='Spread options'><i className='fas fa-gear' /></AnchoredTrigger>
<AnchoredBox title='Options'>
<h1>Options</h1>
<label title='Modify the horizontal space between pages.'>
Column gap
<input type='range' min={0} max={200} defaultValue={10} className='range-input' onChange={(evt)=>handleOptionChange('columnGap', evt.target.value)} />
</label>
<label title='Modify the vertical space between rows of pages.'>
Row gap
<input type='range' min={0} max={200} defaultValue={10} className='range-input' onChange={(evt)=>handleOptionChange('rowGap', evt.target.value)} />
</label>
<label title='Start 1st page on the right side, such as if you have cover page.'>
Start on right
<input type='checkbox' checked={displayOptions.startOnRight} onChange={()=>{handleOptionChange('startOnRight', !displayOptions.startOnRight);}}
title={displayOptions.spread !== 'facing' ? 'Switch to Facing to enable toggle.' : null} />
</label>
<label title='Toggle the page shadow on every page.'>
Page shadows
<input type='checkbox' checked={displayOptions.pageShadows} onChange={()=>{handleOptionChange('pageShadows', !displayOptions.pageShadows);}} />
</label>
</AnchoredBox>
</Anchored>
</div>
{/*v=====----------------------< Page Controls >---------------------=====v*/}
<div className='group' role='group' aria-label='Pages' aria-hidden={!toolsVisible}>
<button
id='previous-page'
className='previousPage tool'
type='button'
title='Previous Page(s)'
onClick={()=>scrollToPage(pageNum - 1)}
disabled={pageNum <= 1}
>
<i className='fas fa-arrow-left'></i>
</button>
<div className='tool'>
<input
id='page-input'
className='text-input'
type='text'
name='page'
title='Current page(s) in view'
inputMode='numeric'
pattern='[0-9]'
value={pageNum}
onClick={(e)=>e.target.select()}
onChange={(e)=>handlePageInput(e.target.value)}
onBlur={()=>scrollToPage(pageNum)}
onKeyDown={(e)=>e.key == 'Enter' && scrollToPage(pageNum)}
/>
<span id='page-count' title='Total Page Count'>/ {totalPages}</span>
</div>
<button
id='next-page'
className='tool'
type='button'
title='Next Page(s)'
onClick={()=>scrollToPage(pageNum + 1)}
disabled={pageNum >= totalPages}
>
<i className='fas fa-arrow-right'></i>
</button>
</div>
</div>
);
};
module.exports = ToolBar;

View File

@@ -0,0 +1,187 @@
@import (less) './client/icons/customIcons.less';
.toolBar {
position : absolute;
z-index : 1;
box-sizing : border-box;
display : flex;
flex-wrap : wrap;
gap : 8px 30px;
align-items : center;
justify-content : center;
width : 100%;
height : auto;
padding : 2px 0;
font-family : 'Open Sans', sans-serif;
font-size : 13px;
color : #CCCCCC;
background-color : #555555;
& > *:not(.toggleButton) {
opacity : 1;
transition : all 0.2s ease;
}
.group {
box-sizing : border-box;
display : flex;
gap : 0 3px;
align-items : center;
justify-content : center;
height : 28px;
}
.tool {
display : flex;
align-items : center;
}
.active, [aria-checked='true'] { background-color : #444444; }
.anchored-trigger {
&.active { background-color : #444444; }
}
.anchored-box {
--box-color : #555555;
top : 30px;
display : flex;
flex-direction : column;
gap : 5px;
padding : 15px;
margin-top : 10px;
font-size : 0.8em;
color : #CCCCCC;
background-color : var(--box-color);
border-radius : 5px;
h1 {
padding-bottom : 0.3em;
margin-bottom : 0.5em;
border-bottom : 1px solid currentColor;
}
h2 {
padding-bottom : 0.3em;
margin : 1em 0 0.5em 0;
color : lightgray;
border-bottom : 1px solid currentColor;
}
label {
display : flex;
gap : 6px;
align-items : center;
justify-content : space-between;
}
input {
height : unset;
&[type='range'] { padding : 0; }
}
&::before {
position : absolute;
top : -20px;
left : 50%;
width : 0px;
height : 0px;
pointer-events : none;
content : '';
border : 10px solid transparent;
border-bottom : 10px solid var(--box-color);
transform : translateX(-50%);
}
}
.radio-group:has(button[role='radio']) {
display : flex;
height : 100%;
border : 1px solid #333333;
}
input {
position : relative;
height : 1.5em;
padding : 2px 5px;
font-family : 'Open Sans', sans-serif;
color : #000000;
background : #EEEEEE;
border : 1px solid gray;
&:focus { outline : 1px solid #D3D3D3; }
// `.range-input` if generic to all range inputs, or `#zoom-slider` if only for zoom slider
&.range-input {
padding : 2px 0;
color : #D3D3D3;
accent-color : #D3D3D3;
&::-webkit-slider-thumb, &::-moz-slider-thumb {
width : 5px;
height : 5px;
cursor : pointer;
outline : none;
}
&.hover-tooltip[value]:hover::after {
position : absolute;
bottom : -30px;
left : 50%;
z-index : 1;
display : grid;
place-items : center;
width : 4ch;
height : 1.2lh;
pointer-events : none;
content : attr(value);
background-color : #555555;
border : 1px solid #A1A1A1;
transform : translate(-50%, 50%);
}
}
// `.text-input` if generic to all range inputs, or `#page-input` if only for current page input
&#page-input {
width : 4ch;
margin-right : 1ch;
text-align : center;
}
}
button {
box-sizing : border-box;
display : flex;
align-items : center;
justify-content : center;
width : auto;
min-width : 46px;
height : 100%;
&:hover { background-color : #444444; }
&:focus { border : 1px solid #D3D3D3;outline : none;}
&:disabled {
color : #777777;
background-color : unset !important;
}
i { font-size : 1.2em; }
}
&.hidden {
flex-wrap : nowrap;
width : 32px;
overflow : hidden;
background-color : unset;
opacity : 0.5;
transition : all 0.3s ease;
& > *:not(.toggleButton) {
opacity : 0;
transition : all 0.2s ease;
}
}
}
button.toggleButton {
position : absolute;
left : 0;
z-index : 5;
width : 32px;
min-width : unset;
}

View File

@@ -1,11 +1,10 @@
/*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/
/*eslint max-lines: ["warn", {"max": 500, "skipBlankLines": true, "skipComments": true}]*/
require('./editor.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');
const dedent = require('dedent-tabs').default;
const Markdown = require('../../../shared/naturalcrit/markdown.js');
import Markdown from '../../../shared/naturalcrit/markdown.js';
const CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx');
const SnippetBar = require('./snippetbar/snippetbar.jsx');
@@ -22,6 +21,7 @@ const DEFAULT_STYLE_TEXT = dedent`
color: black;
}`;
let isJumping = false;
const Editor = createClass({
displayName : 'Editor',
@@ -37,8 +37,15 @@ const Editor = createClass({
onMetaChange : ()=>{},
reportError : ()=>{},
onCursorPageChange : ()=>{},
onViewPageChange : ()=>{},
editorTheme : 'default',
renderer : 'legacy'
renderer : 'legacy',
currentEditorCursorPageNum : 1,
currentEditorViewPageNum : 1,
currentBrewRendererPageNum : 1,
};
},
getInitialState : function() {
@@ -56,9 +63,15 @@ const Editor = createClass({
isMeta : function() {return this.state.view == 'meta';},
componentDidMount : function() {
this.updateEditorSize();
this.highlightCustomMarkdown();
window.addEventListener('resize', this.updateEditorSize);
document.getElementById('BrewRenderer').addEventListener('keydown', this.handleControlKeys);
document.addEventListener('keydown', this.handleControlKeys);
this.codeEditor.current.codeMirror.on('cursorActivity', (cm)=>{this.updateCurrentCursorPage(cm.getCursor());});
this.codeEditor.current.codeMirror.on('scroll', _.throttle(()=>{this.updateCurrentViewPage(this.codeEditor.current.getTopVisibleLine());}, 200));
const editorTheme = window.localStorage.getItem(EDITOR_THEME_KEY);
if(editorTheme) {
@@ -73,13 +86,35 @@ const Editor = createClass({
},
componentDidUpdate : function(prevProps, prevState, snapshot) {
this.highlightCustomMarkdown();
if(prevProps.moveBrew !== this.props.moveBrew) {
if(prevProps.moveBrew !== this.props.moveBrew)
this.brewJump();
};
if(prevProps.moveSource !== this.props.moveSource) {
if(prevProps.moveSource !== this.props.moveSource)
this.sourceJump();
};
if(this.props.liveScroll) {
if(prevProps.currentBrewRendererPageNum !== this.props.currentBrewRendererPageNum) {
this.sourceJump(this.props.currentBrewRendererPageNum, false);
} else if(prevProps.currentEditorViewPageNum !== this.props.currentEditorViewPageNum) {
this.brewJump(this.props.currentEditorViewPageNum, false);
} else if(prevProps.currentEditorCursorPageNum !== this.props.currentEditorCursorPageNum) {
this.brewJump(this.props.currentEditorCursorPageNum, false);
}
}
},
handleControlKeys : function(e){
if(!(e.ctrlKey && e.metaKey && e.shiftKey)) return;
const LEFTARROW_KEY = 37;
const RIGHTARROW_KEY = 39;
if(e.keyCode == RIGHTARROW_KEY) this.brewJump();
if(e.keyCode == LEFTARROW_KEY) this.sourceJump();
if(e.keyCode == LEFTARROW_KEY || e.keyCode == RIGHTARROW_KEY) {
e.stopPropagation();
e.preventDefault();
}
},
updateEditorSize : function() {
@@ -90,6 +125,20 @@ const Editor = createClass({
}
},
updateCurrentCursorPage : function(cursor) {
const lines = this.props.brew.text.split('\n').slice(0, cursor.line + 1);
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
this.props.onCursorPageChange(currentPage);
},
updateCurrentViewPage : function(topScrollLine) {
const lines = this.props.brew.text.split('\n').slice(0, topScrollLine + 1);
const pageRegex = this.props.brew.renderer == 'V3' ? /^\\page$/ : /\\page/;
const currentPage = lines.reduce((count, line)=>count + (pageRegex.test(line) ? 1 : 0), 1);
this.props.onViewPageChange(currentPage);
},
handleInject : function(injectText){
this.codeEditor.current?.injectText(injectText, false);
},
@@ -98,19 +147,10 @@ const Editor = createClass({
this.props.setMoveArrows(newView === 'text');
this.setState({
view : newView
}, this.updateEditorSize); //TODO: not sure if updateeditorsize needed
},
getCurrentPage : function(){
const lines = this.props.brew.text.split('\n').slice(0, this.codeEditor.current.getCursorPosition().line + 1);
return _.reduce(lines, (r, line)=>{
if(
(this.props.renderer == 'legacy' && line.indexOf('\\page') !== -1)
||
(this.props.renderer == 'V3' && line.match(/^\\page$/))
) r++;
return r;
}, 1);
}, ()=>{
this.codeEditor.current?.codeMirror.focus();
this.updateEditorSize();
}); //TODO: not sure if updateeditorsize needed
},
highlightCustomMarkdown : function(){
@@ -119,8 +159,19 @@ const Editor = createClass({
const codeMirror = this.codeEditor.current.codeMirror;
codeMirror.operation(()=>{ // Batch CodeMirror styling
const foldLines = [];
//reset custom text styles
const customHighlights = codeMirror.getAllMarks().filter((mark)=>!mark.__isFold); //Don't undo code folding
const customHighlights = codeMirror.getAllMarks().filter((mark)=>{
// Record details of folded sections
if(mark.__isFold) {
const fold = mark.find();
foldLines.push({ from: fold.from?.line, to: fold.to?.line });
}
return !mark.__isFold;
}); //Don't undo code folding
for (let i=customHighlights.length - 1;i>=0;i--) customHighlights[i].clear();
let editorPageCount = 2; // start page count from page 2
@@ -132,6 +183,11 @@ const Editor = createClass({
codeMirror.removeLineClass(lineNumber, 'text');
codeMirror.removeLineClass(lineNumber, 'wrap', 'sourceMoveFlash');
// Don't process lines inside folded text
// If the current lineNumber is inside any folded marks, skip line styling
if(foldLines.some((fold)=>lineNumber >= fold.from && lineNumber <= fold.to))
return;
// Styling for \page breaks
if((this.props.renderer == 'legacy' && line.includes('\\page')) ||
(this.props.renderer == 'V3' && line.match(/^\\page$/))) {
@@ -155,7 +211,7 @@ const Editor = createClass({
// definition lists
if(line.includes('::')){
if(/^:*$/.test(line) == true){ return };
if(/^:*$/.test(line) == true){ return; };
const regex = /^([^\n]*?:?\s?)(::[^\n]*)(?:\n|$)/ymd; // the `d` flag, for match indices, throws an ESLint error.
let match;
while ((match = regex.exec(line)) != null){
@@ -163,10 +219,10 @@ const Editor = createClass({
codeMirror.markText({ line: lineNumber, ch: match.indices[1][0] }, { line: lineNumber, ch: match.indices[1][1] }, { className: 'dt-highlight' });
codeMirror.markText({ line: lineNumber, ch: match.indices[2][0] }, { line: lineNumber, ch: match.indices[2][1] }, { className: 'dd-highlight' });
const ddIndex = match.indices[2][0];
let colons = /::/g;
let colonMatches = colons.exec(match[2]);
const colons = /::/g;
const colonMatches = colons.exec(match[2]);
if(colonMatches !== null){
codeMirror.markText({ line: lineNumber, ch: colonMatches.index + ddIndex }, { line: lineNumber, ch: colonMatches.index + colonMatches[0].length + ddIndex }, { className: 'dl-colon-highlight'} )
codeMirror.markText({ line: lineNumber, ch: colonMatches.index + ddIndex }, { line: lineNumber, ch: colonMatches.index + colonMatches[0].length + ddIndex }, { className: 'dl-colon-highlight' });
}
}
}
@@ -176,12 +232,12 @@ const Editor = createClass({
let startIndex = line.indexOf('^');
const superRegex = /\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^/gy;
const subRegex = /\^\^(?!\s)(?=([^\n\^]*[^\s\^]))\1\^\^/gy;
while (startIndex >= 0) {
superRegex.lastIndex = subRegex.lastIndex = startIndex;
let isSuper = false;
let match = subRegex.exec(line) || superRegex.exec(line);
if (match) {
const match = subRegex.exec(line) || superRegex.exec(line);
if(match) {
isSuper = !subRegex.lastIndex;
codeMirror.markText({ line: lineNumber, ch: match.index }, { line: lineNumber, ch: match.index + match[0].length }, { className: isSuper ? 'superscript' : 'subscript' });
}
@@ -231,20 +287,20 @@ const Editor = createClass({
while (startIndex >= 0) {
emojiRegex.lastIndex = startIndex;
let match = emojiRegex.exec(line);
if (match) {
const match = emojiRegex.exec(line);
if(match) {
let tokens = Markdown.marked.lexer(match[0]);
tokens = tokens[0].tokens.filter(t => t.type == 'emoji')
if (!tokens.length)
tokens = tokens[0].tokens.filter((t)=>t.type == 'emoji');
if(!tokens.length)
return;
let startPos = { line: lineNumber, ch: match.index };
let endPos = { line: lineNumber, ch: match.index + match[0].length };
const startPos = { line: lineNumber, ch: match.index };
const endPos = { line: lineNumber, ch: match.index + match[0].length };
// Iterate over conflicting marks and clear them
var marks = codeMirror.findMarks(startPos, endPos);
const marks = codeMirror.findMarks(startPos, endPos);
marks.forEach(function(marker) {
marker.clear();
if(!marker.__isFold) marker.clear();
});
codeMirror.markText(startPos, endPos, { className: 'emoji' });
}
@@ -257,75 +313,93 @@ const Editor = createClass({
}
},
brewJump : function(targetPage=this.getCurrentPage()){
if(!window) return;
// console.log(`Scroll to: p${targetPage}`);
brewJump : function(targetPage=this.props.currentEditorCursorPageNum, smooth=true){
if(!window || !this.isText() || isJumping)
return;
// Get current brewRenderer scroll position and calculate target position
const brewRenderer = window.frames['BrewRenderer'].contentDocument.getElementsByClassName('brewRenderer')[0];
const currentPos = brewRenderer.scrollTop;
const targetPos = window.frames['BrewRenderer'].contentDocument.getElementById(`p${targetPage}`).getBoundingClientRect().top;
const interimPos = targetPos >= 0 ? -30 : 30;
const bounceDelay = 100;
const scrollDelay = 500;
if(!this.throttleBrewMove) {
this.throttleBrewMove = _.throttle((currentPos, interimPos, targetPos)=>{
brewRenderer.scrollTo({ top: currentPos + interimPos, behavior: 'smooth' });
setTimeout(()=>{
brewRenderer.scrollTo({ top: currentPos + targetPos, behavior: 'smooth', block: 'start' });
}, bounceDelay);
}, scrollDelay, { leading: true, trailing: false });
const checkIfScrollComplete = ()=>{
let scrollingTimeout;
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
scrollingTimeout = setTimeout(()=>{
isJumping = false;
brewRenderer.removeEventListener('scroll', checkIfScrollComplete);
}, 150); // If 150 ms pass without a brewRenderer scroll event, assume scrolling is done
};
this.throttleBrewMove(currentPos, interimPos, targetPos);
// const hashPage = (page != 1) ? `p${page}` : '';
// window.location.hash = hashPage;
isJumping = true;
checkIfScrollComplete();
brewRenderer.addEventListener('scroll', checkIfScrollComplete);
if(smooth) {
const bouncePos = targetPos >= 0 ? -30 : 30; //Do a little bounce before scrolling
const bounceDelay = 100;
const scrollDelay = 500;
if(!this.throttleBrewMove) {
this.throttleBrewMove = _.throttle((currentPos, bouncePos, targetPos)=>{
brewRenderer.scrollTo({ top: currentPos + bouncePos, behavior: 'smooth' });
setTimeout(()=>{
brewRenderer.scrollTo({ top: currentPos + targetPos, behavior: 'smooth', block: 'start' });
}, bounceDelay);
}, scrollDelay, { leading: true, trailing: false });
};
this.throttleBrewMove(currentPos, bouncePos, targetPos);
} else {
brewRenderer.scrollTo({ top: currentPos + targetPos, behavior: 'instant', block: 'start' });
}
},
sourceJump : function(targetLine=null){
if(this.isText()) {
if(targetLine == null) {
targetLine = 0;
sourceJump : function(targetPage=this.props.currentBrewRendererPageNum, smooth=true){
if(!this.isText() || isJumping)
return;
const pageCollection = window.frames['BrewRenderer'].contentDocument.getElementsByClassName('page');
const brewRendererHeight = window.frames['BrewRenderer'].contentDocument.getElementsByClassName('brewRenderer').item(0).getBoundingClientRect().height;
const textSplit = this.props.renderer == 'V3' ? /^\\page$/gm : /\\page/;
const textString = this.props.brew.text.split(textSplit).slice(0, targetPage-1).join(textSplit);
const targetLine = textString.match('\n') ? textString.split('\n').length - 1 : -1;
let currentPage = 1;
for (const page of pageCollection) {
if(page.getBoundingClientRect().bottom > (brewRendererHeight / 2)) {
currentPage = parseInt(page.id.slice(1)) || 1;
break;
}
let currentY = this.codeEditor.current.codeMirror.getScrollInfo().top;
let targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
const checkIfScrollComplete = ()=>{
let scrollingTimeout;
clearTimeout(scrollingTimeout); // Reset the timer every time a scroll event occurs
scrollingTimeout = setTimeout(()=>{
isJumping = false;
this.codeEditor.current.codeMirror.off('scroll', checkIfScrollComplete);
}, 150); // If 150 ms pass without a scroll event, assume scrolling is done
};
isJumping = true;
checkIfScrollComplete();
this.codeEditor.current.codeMirror.on('scroll', checkIfScrollComplete);
if(smooth) {
//Scroll 1/10 of the way every 10ms until 1px off.
const incrementalScroll = setInterval(()=>{
currentY += (targetY - currentY) / 10;
this.codeEditor.current.codeMirror.scrollTo(null, currentY);
// Update target: target height is not accurate until within +-10 lines of the visible window
if(Math.abs(targetY - currentY > 100))
targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
// End when close enough
if(Math.abs(targetY - currentY) < 1) {
this.codeEditor.current.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
this.codeEditor.current.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
clearInterval(incrementalScroll);
}
const textSplit = this.props.renderer == 'V3' ? /^\\page$/gm : /\\page/;
const textString = this.props.brew.text.split(textSplit).slice(0, currentPage-1).join(textSplit);
const textPosition = textString.length;
const lineCount = textString.match('\n') ? textString.slice(0, textPosition).split('\n').length : 0;
targetLine = lineCount - 1; //Scroll to `\page`, which is one line back.
let currentY = this.codeEditor.current.codeMirror.getScrollInfo().top;
let targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
//Scroll 1/10 of the way every 10ms until 1px off.
const incrementalScroll = setInterval(()=>{
currentY += (targetY - currentY) / 10;
this.codeEditor.current.codeMirror.scrollTo(null, currentY);
// Update target: target height is not accurate until within +-10 lines of the visible window
if(Math.abs(targetY - currentY > 100))
targetY = this.codeEditor.current.codeMirror.heightAtLine(targetLine, 'local', true);
// End when close enough
if(Math.abs(targetY - currentY) < 1) {
this.codeEditor.current.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
this.codeEditor.current.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
clearInterval(incrementalScroll);
}
}, 10);
}
}, 10);
} else {
this.codeEditor.current.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference
this.codeEditor.current.setCursorPosition({ line: targetLine + 1, ch: 0 });
this.codeEditor.current.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash');
}
},
@@ -367,7 +441,7 @@ const Editor = createClass({
view={this.state.view}
value={this.props.brew.style ?? DEFAULT_STYLE_TEXT}
onChange={this.props.onStyleChange}
enableFolding={false}
enableFolding={true}
editorTheme={this.state.editorTheme}
rerenderParent={this.rerenderParent} />
</>;
@@ -381,7 +455,8 @@ const Editor = createClass({
<MetadataEditor
metadata={this.props.brew}
onChange={this.props.onMetaChange}
reportError={this.props.reportError}/>
reportError={this.props.reportError}
userThemes={this.props.userThemes}/>
</>;
}
},
@@ -424,7 +499,10 @@ const Editor = createClass({
historySize={this.historySize()}
currentEditorTheme={this.state.editorTheme}
updateEditorTheme={this.updateEditorTheme}
cursorPos={this.codeEditor.current?.getCursorPosition() || {}} />
snippetBundle={this.props.snippetBundle}
cursorPos={this.codeEditor.current?.getCursorPosition() || {}}
updateBrew={this.props.updateBrew}
/>
{this.renderEditor()}
</div>

View File

@@ -2,6 +2,7 @@
.editor {
position : relative;
width : 100%;
container: editor / inline-size;
.codeEditor {
height : 100%;

View File

@@ -3,10 +3,11 @@ require('./metadataEditor.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const request = require('../../utils/request-middleware.js');
import request from '../../utils/request-middleware.js';
const Nav = require('naturalcrit/nav/nav.jsx');
const Combobox = require('client/components/combobox.jsx');
const StringArrayEditor = require('../stringArrayEditor/stringArrayEditor.jsx');
const TagInput = require('../tagInput/tagInput.jsx');
const Themes = require('themes/themes.json');
const validations = require('./validations.js');
@@ -27,6 +28,7 @@ const MetadataEditor = createClass({
return {
metadata : {
editId : null,
shareId : null,
title : '',
description : '',
thumbnail : '',
@@ -98,7 +100,7 @@ const MetadataEditor = createClass({
if(renderer == 'legacy')
this.props.metadata.theme = '5ePHB';
}
this.props.onChange(this.props.metadata);
this.props.onChange(this.props.metadata, 'renderer');
},
handlePublish : function(val){
this.props.onChange({
@@ -110,7 +112,7 @@ const MetadataEditor = createClass({
handleTheme : function(theme){
this.props.metadata.renderer = theme.renderer;
this.props.metadata.theme = theme.path;
this.props.onChange(this.props.metadata);
this.props.onChange(this.props.metadata, 'theme');
},
handleLanguage : function(languageCode){
@@ -191,37 +193,42 @@ const MetadataEditor = createClass({
renderThemeDropdown : function(){
if(!global.enable_themes) return;
const mergedThemes = _.merge(Themes, this.props.userThemes);
const listThemes = (renderer)=>{
return _.map(_.values(Themes[renderer]), (theme)=>{
return <div className='item' key={''} onClick={()=>this.handleTheme(theme)} title={''}>
{`${theme.renderer} : ${theme.name}`}
<img src={`/themes/${theme.renderer}/${theme.path}/dropdownTexture.png`}/>
return _.map(_.values(mergedThemes[renderer]), (theme)=>{
if(theme.path == this.props.metadata.shareId) return;
const preview = theme.thumbnail || `/themes/${theme.renderer}/${theme.path}/dropdownPreview.png`;
const texture = theme.thumbnail || `/themes/${theme.renderer}/${theme.path}/dropdownTexture.png`;
return <div className='item' key={`${renderer}_${theme.name}`} onClick={()=>this.handleTheme(theme)} title={''}>
{theme.author ?? renderer} : {theme.name}
<div className='texture-container'>
<img src={texture}/>
</div>
<div className='preview'>
<h6>{`${theme.name}`} preview</h6>
<img src={`/themes/${theme.renderer}/${theme.path}/dropdownPreview.png`}/>
<h6>{theme.name} preview</h6>
<img src={preview}/>
</div>
</div>;
});
};
const currentTheme = Themes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme];
const currentRenderer = this.props.metadata.renderer;
const currentTheme = mergedThemes[`${_.upperFirst(this.props.metadata.renderer)}`][this.props.metadata.theme]
?? { name: `!!! THEME MISSING !!! ID=${this.props.metadata.theme}` };
let dropdown;
if(this.props.metadata.renderer == 'legacy') {
if(currentRenderer == 'legacy') {
dropdown =
<Nav.dropdown className='disabled value' trigger='disabled'>
<div>
{`Themes are not supported in the Legacy Renderer`} <i className='fas fa-caret-down'></i>
</div>
<div> {`Themes are not supported in the Legacy Renderer`} <i className='fas fa-caret-down'></i> </div>
</Nav.dropdown>;
} else {
dropdown =
<Nav.dropdown className='value' trigger='click'>
<div>
{`${_.upperFirst(currentTheme.renderer)} : ${currentTheme.name}`} <i className='fas fa-caret-down'></i>
</div>
{/*listThemes('Legacy')*/}
{listThemes('V3')}
<div> {currentTheme.author ?? _.upperFirst(currentRenderer)} : {currentTheme.name} <i className='fas fa-caret-down'></i> </div>
{listThemes(currentRenderer)}
</Nav.dropdown>;
}
@@ -297,17 +304,14 @@ const MetadataEditor = createClass({
onChange={(e)=>this.handleRenderer('V3', e)} />
V3
</label>
<a href='/legacy' target='_blank' rel='noopener noreferrer'>
Click here to see the demo page for the old Legacy renderer!
</a>
<small><a href='/legacy' target='_blank' rel='noopener noreferrer'>Click here to see the demo page for the old Legacy renderer!</a></small>
</div>
</div>;
},
render : function(){
return <div className='metadataEditor'>
<h1 className='sectionHead'>Brew</h1>
<h1>Properties Editor</h1>
<div className='field title'>
<label>title</label>
@@ -337,10 +341,11 @@ const MetadataEditor = createClass({
{this.renderThumbnail()}
</div>
<StringArrayEditor label='tags' valuePatterns={[/^(?:(?:group|meta|system|type):)?[A-Za-z0-9][A-Za-z0-9 \/.\-]{0,40}$/]}
<TagInput label='tags' valuePatterns={[/^(?:(?:group|meta|system|type):)?[A-Za-z0-9][A-Za-z0-9 \/.\-]{0,40}$/]}
placeholder='add tag' unique={true}
values={this.props.metadata.tags}
onChange={(e)=>this.handleFieldChange('tags', e)}/>
onChange={(e)=>this.handleFieldChange('tags', e)}
/>
<div className='field systems'>
<label>systems</label>
@@ -355,28 +360,25 @@ const MetadataEditor = createClass({
{this.renderRenderOptions()}
<hr/>
<h1 className='sectionHead'>Authors</h1>
<h2>Authors</h2>
{this.renderAuthors()}
<StringArrayEditor label='invited authors' valuePatterns={[/.+/]}
<TagInput label='invited authors' valuePatterns={[/.+/]}
validators={[(v)=>!this.props.metadata.authors?.includes(v)]}
placeholder='invite author' unique={true}
values={this.props.metadata.invitedAuthors}
notes={['Invited author usernames are case sensitive.', 'After adding an invited author, send them the edit link. There, they can choose to accept or decline the invitation.']}
onChange={(e)=>this.handleFieldChange('invitedAuthors', e)}/>
onChange={(e)=>this.handleFieldChange('invitedAuthors', e)}
/>
<hr/>
<h1 className='sectionHead'>Privacy</h1>
<h2>Privacy</h2>
<div className='field publish'>
<label>publish</label>
<div className='value'>
{this.renderPublish()}
<small>Published homebrews will be publicly viewable and searchable (eventually...)</small>
<small>Published brews are searchable in <a href='/vault'>the Vault</a> and visible on your user page. Unpublished brews are not indexed in the Vault or visible on your user page, but can still be shared and indexed by search engines. You can unpublish a brew any time.</small>
</div>
</div>

View File

@@ -1,328 +1,324 @@
@import 'naturalcrit/styles/colors.less';
.metadataEditor{
.metadataEditor {
position : absolute;
z-index : 5;
box-sizing : border-box;
width : 100%;
padding : 25px;
background-color : #999;
height : calc(100vh - 54px); // 54px is the height of the navbar + snippet bar. probably a better way to dynamic get this.
padding : 25px;
overflow-y : auto;
background-color : #999999;
font-size : 13px;
.sectionHead {
font-weight: 1000;
margin: 20px 0;
&:first-of-type {
margin-top: 0;
}
h1 {
margin: 0 0 40px;
font-weight: bold;
text-transform: uppercase;
}
h2 {
margin : 20px 0;
font-weight : bold;
border-bottom: 2px solid gray;
color: #555;
}
& > div {
margin-bottom: 10px;
}
& > div { margin-bottom : 10px; }
.field-group {
display: flex;
width: 100%;
flex-wrap: wrap;
gap: 10px;
display : flex;
flex-wrap : wrap;
gap : 10px;
width : 100%;
}
.field-column {
display: flex;
flex-direction: column;
flex: 5 0 200px;
gap: 10px;
display : flex;
flex : 5 0 200px;
flex-direction : column;
gap : 10px;
}
.field{
.field {
position : relative;
display : flex;
flex-wrap : wrap;
width : 100%;
min-width : 200px;
position : relative;
&>label{
& > label {
width : 80px;
font-size : 11px;
font-weight : 800;
line-height : 1.8em;
text-transform : uppercase;
font-size: .9em;
}
&>.value{
& > .value {
flex : 1 1 auto;
width : 50px;
&:invalid {
background : #ffb9b9;
&:invalid { background : #FFB9B9; }
small {
display : block;
font-size : 0.9em;
font-style : italic;
line-height : 1.4em;
}
}
input[type='text'], textarea {
border : 1px solid gray;
&:focus {
outline: 1px solid #444;
}
&:focus { outline : 1px solid #444444; }
}
&.thumbnail{
&.thumbnail {
height : 1.4em;
label{
line-height: 2.0em;
label { line-height : 2.0em; }
.value {
overflow : hidden;
text-overflow : ellipsis;
}
.value{
overflow: hidden;
text-overflow: ellipsis;
}
button{
border: 1px solid #999;
color: white;
padding: 0px 5px;
background-color: black;
&:hover{
background-color: #777;
}
button {
.colorButton();
padding : 0px 5px;
color : white;
background-color : black;
border : 1px solid #999999;
&:hover { background-color : #777777; }
}
}
&.description {
flex: 1;
flex : 1;
textarea.value {
resize : none;
height : auto;
font-family : 'Open Sans', sans-serif;
font-size : 0.8em;
resize : none;
}
}
&.language .language-dropdown {
max-width : 150px;
z-index : 200;
}
small {
font-size : 0.6em;
font-style : italic;
line-height : 1.4em;
display : inline-block;
max-width : 150px;
}
}
.thumbnail-preview {
position: relative;
justify-self: center;
width: 80px;
height: min-content;
flex: 1 1;
max-height: 115px;
aspect-ratio: 1 / 1;
object-fit: contain;
background-color: #AAA;
position : relative;
flex : 1 1;
justify-self : center;
width : 80px;
height : min-content;
max-height : 115px;
aspect-ratio : 1 / 1;
object-fit : contain;
background-color : #AAAAAA;
}
.systems.field .value{
label{
vertical-align : middle;
margin-right : 15px;
cursor : pointer;
font-size : 0.7em;
font-weight : 800;
user-select : none;
white-space : nowrap;
.systems.field .value {
label {
display : inline-flex;
align-items : center;
}
a {
font-size : 0.7em;
font-weight : 800;
display : inline-flex;
}
input{
margin-right : 15px;
font-size : 0.9em;
font-weight : 800;
white-space : nowrap;
vertical-align : middle;
cursor : pointer;
user-select : none;
}
input {
margin : 3px;
vertical-align : middle;
cursor : pointer;
}
}
.publish.field .value{
position : relative;
margin-bottom: 15px;
button{
width:100%;
.publish.field .value {
position : relative;
margin-bottom : 15px;
button { width : 100%; }
button.publish {
.colorButton(@blueLight);
}
button.publish{
.button(@blueLight);
}
button.unpublish{
.button(@silver);
button.unpublish {
.colorButton(@silver);
}
}
.delete.field .value{
button{
.button(@red);
.delete.field .value {
button {
.colorButton(@red);
}
}
.authors.field .value{
font-size: 0.8em;
.authors.field .value {
line-height : 1.5em;
}
.themes.field{
font-size : 13.33px;
.themes.field {
.navDropdownContainer {
background-color : white;
position : relative;
z-index : 100;
position : relative;
z-index : 100;
background-color : white;
&.disabled {
font-style :italic;
font-style : italic;
background-color : darkgray;
color : dimgray;
font-style : italic;
color : dimgray;
background-color : darkgray;
}
&>div:first-child {
border : 2px solid rgb(118,118,118);
padding : 6px 3px;
background-color : inherit;
i {
float : right;
}
& > div:first-child {
padding : 3px 3px;
background-color : inherit;
border : 1px solid gray;
i { float : right; }
&:hover {
background-color : @blue;
color : white;
color : white;
background-color : @blue;
}
}
.navDropdown .item > p {
width : 45%;
height : 1.1em;
overflow : hidden;
text-overflow : ellipsis;
white-space : nowrap;
}
.navDropdown {
box-shadow : 0px 5px 10px rgba(0, 0, 0, 0.3);
position : absolute;
width : 100%;
box-shadow : 0px 5px 10px rgba(0, 0, 0, 0.3);
.item {
padding : 3px 3px;
border-top : 1px solid rgb(118, 118, 118);
position : relative;
padding : 3px 3px;
overflow : visible;
background-color : white;
background-color : white;
border-top : 1px solid rgb(118, 118, 118);
.preview {
display : flex;
flex-direction: column;
background : #ccc;
border-radius : 5px;
box-shadow : 0 0 5px black;
width : 200px;
color :black;
position : absolute;
top : 0;
right : 0;
opacity : 0;
transition : opacity 250ms ease;
z-index : 1;
overflow :hidden;
position : absolute;
top : 0;
right : 0;
z-index : 1;
display : flex;
flex-direction : column;
width : 200px;
overflow : hidden;
color : black;
background : #CCCCCC;
border-radius : 5px;
box-shadow : 0 0 5px black;
opacity : 0;
transition : opacity 250ms ease;
h6 {
font-weight : 900;
padding-inline:1em;
padding-block :.5em;
border-bottom :2px solid hsl(0,0%,40%);
padding-block : 0.5em;
padding-inline : 1em;
font-weight : 900;
border-bottom : 2px solid hsl(0,0%,40%);
}
}
&:hover {
background-color : @blue;
color : white;
color : white;
background-color : @blue;
}
&:hover > .preview {
opacity: 1;
}
>img {
mask-image : linear-gradient(90deg, transparent, black 20%);
-webkit-mask-image : linear-gradient(90deg, transparent, black 20%);
position : absolute;
right : 0;
top : 0px;
width : 50%;
height : 100%;
&:hover > .preview { opacity : 1; }
.texture-container {
position : absolute;
top : 0;
left : 0;
width : 100%;
height : 100%;
min-height : 100%;
overflow : hidden;
> img {
position : absolute;
top : 0px;
right : 0;
width : 50%;
min-height : 100%;
-webkit-mask-image : linear-gradient(90deg, transparent, black 20%);
mask-image : linear-gradient(90deg, transparent, black 20%);
}
}
}
}
}
}
.field .list {
display: flex;
flex: 1 0;
flex-wrap: wrap;
> * {
flex: 0 0 auto;
}
.field .list {
display : flex;
flex : 1 0;
flex-wrap : wrap;
> * { flex : 0 0 auto; }
#groupedIcon {
#backgroundColors;
display: inline-block;
height: ~"calc(100% + 0.6em)";
position: relative;
top: -0.3em;
right: -0.3em;
cursor: pointer;
min-width: 20px;
text-align: center;
color: white;
position : relative;
top : -0.3em;
right : -0.3em;
display : inline-block;
min-width : 20px;
height : ~'calc(100% + 0.6em)';
color : white;
text-align : center;
cursor : pointer;
i {
position: relative;
top: 50%;
transform: translateY(-50%);
}
&:not(:last-child) {
border-right: 1px solid black;
}
&:last-child {
border-radius: 0 0.5em 0.5em 0;
position : relative;
top : 50%;
transform : translateY(-50%);
}
&:not(:last-child) { border-right : 1px solid black; }
&:last-child { border-radius : 0 0.5em 0.5em 0; }
}
.badge {
background-color: #dddddd;
border-radius: .5em;
font-size: .9em;
margin: 2px;
padding: .3em;
.tag {
padding : 0.3em;
margin : 2px;
font-size : 0.9em;
background-color : #DDDDDD;
border-radius : 0.5em;
.icon {
#groupedIcon
}
.icon { #groupedIcon; }
}
.input-group {
height: ~"calc(.9em + 4px + .6em)";
height : ~'calc(.9em + 4px + .6em)';
input {
border-radius: .5em 0 0 .5em;
}
input { border-radius : 0.5em 0 0 0.5em; }
input:last-child {
border-radius: .5em;
}
input:last-child { border-radius : 0.5em; }
.value {
width: 7.5vw;
min-width: 75px;
height: 100%;
width : 7.5vw;
min-width : 75px;
height : 100%;
}
.invalid:focus {
background-color: pink;
}
.input-group {
height : ~'calc(.9em + 4px + .6em)';
.icon {
#groupedIcon;
height: 97%;
font-size: .8em;
right: 1px;
top: -.54em;
input { border-radius : 0.5em 0 0 0.5em; }
i {
font-size: 1.125em;
input:last-child { border-radius : 0.5em; }
.value {
width : 7.5vw;
min-width : 75px;
height : 100%;
}
.invalid:focus { background-color : pink; }
.icon {
#groupedIcon;
top : -0.54em;
right : 1px;
height : 97%;
i { font-size : 1.125em; }
}
}
}
}
}
}

View File

@@ -1,14 +1,13 @@
/*eslint max-lines: ["warn", {"max": 250, "skipBlankLines": true, "skipComments": true}]*/
/*eslint max-lines: ["warn", {"max": 350, "skipBlankLines": true, "skipComments": true}]*/
require('./snippetbar.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');
import { loadHistory } from '../../utils/versionHistory.js';
//Import all themes
const Themes = require('themes/themes.json');
const ThemeSnippets = {};
ThemeSnippets['Legacy_5ePHB'] = require('themes/Legacy/5ePHB/snippets.js');
ThemeSnippets['V3_5ePHB'] = require('themes/V3/5ePHB/snippets.js');
@@ -40,7 +39,9 @@ const Snippetbar = createClass({
foldCode : ()=>{},
unfoldCode : ()=>{},
updateEditorTheme : ()=>{},
cursorPos : {}
cursorPos : {},
snippetBundle : [],
updateBrew : ()=>{}
};
},
@@ -48,53 +49,70 @@ const Snippetbar = createClass({
return {
renderer : this.props.renderer,
themeSelector : false,
snippets : []
snippets : [],
showHistory : false,
historyExists : false,
historyItems : []
};
},
componentDidMount : async function() {
const rendererPath = this.props.renderer == 'V3' ? 'V3' : 'Legacy';
const themePath = this.props.theme ?? '5ePHB';
let snippets = _.cloneDeep(ThemeSnippets[`${rendererPath}_${themePath}`]);
snippets = this.compileSnippets(rendererPath, themePath, snippets);
componentDidMount : async function(prevState) {
const snippets = this.compileSnippets();
this.setState({
snippets : snippets
});
},
componentDidUpdate : async function(prevProps) {
if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme) {
const rendererPath = this.props.renderer == 'V3' ? 'V3' : 'Legacy';
const themePath = this.props.theme ?? '5ePHB';
let snippets = _.cloneDeep(ThemeSnippets[`${rendererPath}_${themePath}`]);
snippets = this.compileSnippets(rendererPath, themePath, snippets);
componentDidUpdate : async function(prevProps, prevState) {
if(prevProps.renderer != this.props.renderer || prevProps.theme != this.props.theme || prevProps.snippetBundle != this.props.snippetBundle) {
this.setState({
snippets : snippets
snippets : this.compileSnippets()
});
};
// Update history list if it has changed
const checkHistoryItems = await loadHistory(this.props.brew);
// If all items have the noData property, there is no saved data
const checkHistoryExists = !checkHistoryItems.every((historyItem)=>{
return historyItem?.noData;
});
if(prevState.historyExists != checkHistoryExists){
this.setState({
historyExists : checkHistoryExists
});
}
// If any history items have changed, update the list
if(checkHistoryExists && checkHistoryItems.some((historyItem, index)=>{
return index >= prevState.historyItems.length || !_.isEqual(historyItem, prevState.historyItems[index]);
})){
this.setState({
historyItems : checkHistoryItems
});
}
},
mergeCustomizer : function(valueA, valueB, key) {
mergeCustomizer : function(oldValue, newValue, key) {
if(key == 'snippets') {
const result = _.reverse(_.unionBy(_.reverse(valueB), _.reverse(valueA), 'name')); // Join snippets together, with preference for the current theme over the base theme
return _.filter(result, 'gen'); //Only keep snippets with a 'gen' property.
const result = _.reverse(_.unionBy(_.reverse(newValue), _.reverse(oldValue), 'name')); // Join snippets together, with preference for the child theme over the parent theme
return result.filter((snip)=>snip.gen || snip.subsnippets);
}
},
compileSnippets : function(rendererPath, themePath, snippets) {
let compiledSnippets = snippets;
const baseSnippetsPath = Themes[rendererPath][themePath].baseSnippets;
compileSnippets : function() {
let compiledSnippets = [];
const objB = _.keyBy(compiledSnippets, 'groupName');
let oldSnippets = _.keyBy(compiledSnippets, 'groupName');
if(baseSnippetsPath) {
const objA = _.keyBy(_.cloneDeep(ThemeSnippets[`${rendererPath}_${baseSnippetsPath}`]), 'groupName');
compiledSnippets = _.values(_.mergeWith(objA, objB, this.mergeCustomizer));
compiledSnippets = this.compileSnippets(rendererPath, baseSnippetsPath, _.cloneDeep(compiledSnippets));
} else {
const objA = _.keyBy(_.cloneDeep(ThemeSnippets[`${rendererPath}_Blank`]), 'groupName');
compiledSnippets = _.values(_.mergeWith(objA, objB, this.mergeCustomizer));
for (let snippets of this.props.snippetBundle) {
if(typeof(snippets) == 'string') // load staticThemes as needed; they were sent as just a file name
snippets = ThemeSnippets[snippets];
const newSnippets = _.keyBy(_.cloneDeep(snippets), 'groupName');
compiledSnippets = _.values(_.mergeWith(oldSnippets, newSnippets, this.mergeCustomizer));
oldSnippets = _.keyBy(compiledSnippets, 'groupName');
}
return compiledSnippets;
},
@@ -132,69 +150,115 @@ const Snippetbar = createClass({
renderSnippetGroups : function(){
const snippets = this.state.snippets.filter((snippetGroup)=>snippetGroup.view === this.props.view);
if(snippets.length === 0) return null;
return _.map(snippets, (snippetGroup)=>{
return <SnippetGroup
brew={this.props.brew}
groupName={snippetGroup.groupName}
icon={snippetGroup.icon}
snippets={snippetGroup.snippets}
key={snippetGroup.groupName}
onSnippetClick={this.handleSnippetClick}
cursorPos={this.props.cursorPos}
/>;
return <div className='snippets'>
{_.map(snippets, (snippetGroup)=>{
return <SnippetGroup
brew={this.props.brew}
groupName={snippetGroup.groupName}
icon={snippetGroup.icon}
snippets={snippetGroup.snippets}
key={snippetGroup.groupName}
onSnippetClick={this.handleSnippetClick}
cursorPos={this.props.cursorPos}
/>;
})
}
</div>;
},
replaceContent : function(item){
return this.props.updateBrew(item);
},
toggleHistoryMenu : function(){
this.setState({
showHistory : !this.state.showHistory
});
},
renderHistoryItems : function() {
if(!this.state.historyExists) return;
return <div className='dropdown'>
{_.map(this.state.historyItems, (item, index)=>{
if(item.noData || !item.savedAt) return;
const saveTime = new Date(item.savedAt);
const diffMs = new Date() - saveTime;
const diffSecs = Math.floor(diffMs / 1000);
let diffString = `about ${diffSecs} seconds ago`;
if(diffSecs > 60) diffString = `about ${Math.floor(diffSecs / 60)} minutes ago`;
if(diffSecs > (60 * 60)) diffString = `about ${Math.floor(diffSecs / (60 * 60))} hours ago`;
if(diffSecs > (24 * 60 * 60)) diffString = `about ${Math.floor(diffSecs / (24 * 60 * 60))} days ago`;
if(diffSecs > (7 * 24 * 60 * 60)) diffString = `about ${Math.floor(diffSecs / (7 * 24 * 60 * 60))} weeks ago`;
return <div className='snippet' key={index} onClick={()=>{this.replaceContent(item);}} >
<i className={`fas fa-${index+1}`} />
<span className='name' title={saveTime.toISOString()}>v{item.version} : {diffString}</span>
</div>;
})}
</div>;
},
renderEditorButtons : function(){
if(!this.props.showEditButtons) return;
let foldButtons;
if(this.props.view == 'text'){
foldButtons =
<>
<div className={`editorTool foldAll ${this.props.foldCode ? 'active' : ''}`}
onClick={this.props.foldCode} >
<i className='fas fa-compress-alt' />
</div>
<div className={`editorTool unfoldAll ${this.props.unfoldCode ? 'active' : ''}`}
onClick={this.props.unfoldCode} >
<i className='fas fa-expand-alt' />
</div>
</>;
}
const foldButtons = <>
<div className={`editorTool foldAll ${this.props.view !== 'meta' && this.props.foldCode ? 'active' : ''}`}
onClick={this.props.foldCode} >
<i className='fas fa-compress-alt' />
</div>
<div className={`editorTool unfoldAll ${this.props.view !== 'meta' && this.props.unfoldCode ? 'active' : ''}`}
onClick={this.props.unfoldCode} >
<i className='fas fa-expand-alt' />
</div>
</>;
return <div className='editors'>
<div className={`editorTool undo ${this.props.historySize.undo ? 'active' : ''}`}
onClick={this.props.undo} >
<i className='fas fa-undo' />
<div className='historyTools'>
<div className={`editorTool snippetGroup history ${this.state.historyExists ? 'active' : ''}`}
onClick={this.toggleHistoryMenu} >
<i className='fas fa-clock-rotate-left' />
{ this.state.showHistory && this.renderHistoryItems() }
</div>
<div className={`editorTool undo ${this.props.historySize.undo ? 'active' : ''}`}
onClick={this.props.undo} >
<i className='fas fa-undo' />
</div>
<div className={`editorTool redo ${this.props.historySize.redo ? 'active' : ''}`}
onClick={this.props.redo} >
<i className='fas fa-redo' />
</div>
</div>
<div className={`editorTool redo ${this.props.historySize.redo ? 'active' : ''}`}
onClick={this.props.redo} >
<i className='fas fa-redo' />
</div>
<div className='divider'></div>
{foldButtons}
<div className={`editorTool editorTheme ${this.state.themeSelector ? 'active' : ''}`}
onClick={this.toggleThemeSelector} >
<i className='fas fa-palette' />
{this.state.themeSelector && this.renderThemeSelector()}
<div className='codeTools'>
{foldButtons}
<div className={`editorTool editorTheme ${this.state.themeSelector ? 'active' : ''}`}
onClick={this.toggleThemeSelector} >
<i className='fas fa-palette' />
{this.state.themeSelector && this.renderThemeSelector()}
</div>
</div>
<div className='divider'></div>
<div className={cx('text', { selected: this.props.view === 'text' })}
onClick={()=>this.props.onViewChange('text')}>
<i className='fa fa-beer' />
</div>
<div className={cx('style', { selected: this.props.view === 'style' })}
onClick={()=>this.props.onViewChange('style')}>
<i className='fa fa-paint-brush' />
</div>
<div className={cx('meta', { selected: this.props.view === 'meta' })}
onClick={()=>this.props.onViewChange('meta')}>
<i className='fas fa-info-circle' />
<div className='tabs'>
<div className={cx('text', { selected: this.props.view === 'text' })}
onClick={()=>this.props.onViewChange('text')}>
<i className='fa fa-beer' />
</div>
<div className={cx('style', { selected: this.props.view === 'style' })}
onClick={()=>this.props.onViewChange('style')}>
<i className='fa fa-paint-brush' />
</div>
<div className={cx('meta', { selected: this.props.view === 'meta' })}
onClick={()=>this.props.onViewChange('meta')}>
<i className='fas fa-info-circle' />
</div>
</div>
</div>;
},
@@ -232,8 +296,9 @@ const SnippetGroup = createClass({
return _.map(snippets, (snippet)=>{
return <div className='snippet' key={snippet.name} onClick={(e)=>this.handleSnippetClick(e, snippet)}>
<i className={snippet.icon} />
<span className='name'title={snippet.name}>{snippet.name}</span>
<span className={`name${snippet.disabled ? ' disabled' : ''}`} title={snippet.name}>{snippet.name}</span>
{snippet.experimental && <span className='beta'>beta</span>}
{snippet.disabled && <span className='beta' title='temporarily disabled due to large slowdown; under re-design'>disabled</span>}
{snippet.subsnippets && <>
<i className='fas fa-caret-right'></i>
<div className='dropdown side'>

View File

@@ -4,82 +4,114 @@
.snippetBar {
@menuHeight : 25px;
position : relative;
height : @menuHeight;
display : flex;
flex-wrap : wrap-reverse;
justify-content : space-between;
height : auto;
color : black;
background-color : #DDDDDD;
.editors {
position : absolute;
top : 0px;
right : 0px;
.snippets {
display : flex;
justify-content : space-between;
height : @menuHeight;
& > div {
width : @menuHeight;
height : @menuHeight;
line-height : @menuHeight;
text-align : center;
cursor : pointer;
&:hover,&.selected { background-color : #999999; }
&.text {
.tooltipLeft('Brew Editor');
}
&.style {
.tooltipLeft('Style Editor');
}
&.meta {
.tooltipLeft('Properties');
}
&.undo {
.tooltipLeft('Undo');
font-size : 0.75em;
color : grey;
&.active { color : inherit; }
}
&.redo {
.tooltipLeft('Redo');
font-size : 0.75em;
color : grey;
&.active { color : inherit; }
}
&.foldAll {
.tooltipLeft('Fold All');
font-size : 0.75em;
color : inherit;
}
&.unfoldAll {
.tooltipLeft('Unfold All');
font-size : 0.75em;
color : inherit;
}
&.editorTheme {
.tooltipLeft('Editor Themes');
font-size : 0.75em;
color : black;
&.active {
position : relative;
background-color : #999999;
justify-content : flex-start;
min-width : 327.58px;
}
.editors {
display : flex;
justify-content : flex-end;
min-width : 225px;
&:only-child { margin-left : auto; }
>div {
display : flex;
flex : 1;
justify-content : space-around;
&:first-child { border-left : none; }
& > div {
position : relative;
width : @menuHeight;
height : @menuHeight;
line-height : @menuHeight;
text-align : center;
cursor : pointer;
&:hover,&.selected { background-color : #999999; }
&.text {
.tooltipLeft('Brew Editor');
}
&.style {
.tooltipLeft('Style Editor');
}
&.meta {
.tooltipLeft('Properties');
}
&.undo {
.tooltipLeft('Undo');
font-size : 0.75em;
color : grey;
&.active { color : inherit; }
}
&.redo {
.tooltipLeft('Redo');
font-size : 0.75em;
color : grey;
&.active { color : inherit; }
}
&.foldAll {
.tooltipLeft('Fold All');
font-size : 0.75em;
color : grey;
&.active { color : inherit; }
}
&.unfoldAll {
.tooltipLeft('Unfold All');
font-size : 0.75em;
color : grey;
&.active { color : inherit; }
}
&.history {
.tooltipLeft('History');
position : relative;
font-size : 0.75em;
color : grey;
border : none;
&.active { color : inherit; }
& > .dropdown {
right : -1px;
& > .snippet { padding-right : 10px; }
}
}
&.editorTheme {
.tooltipLeft('Editor Themes');
font-size : 0.75em;
color : black;
&.active {
position : relative;
background-color : #999999;
}
}
&.divider {
width : 5px;
background : linear-gradient(currentColor, currentColor) no-repeat center/1px 100%;
&:hover { background-color : inherit; }
}
}
&.divider {
width : 5px;
background : linear-gradient(currentColor, currentColor) no-repeat center/1px 100%;
&:hover { background-color : inherit; }
.themeSelector {
position : absolute;
top : 25px;
right : 0;
z-index : 10;
display : flex;
align-items : center;
justify-content : center;
width : 170px;
height : inherit;
background-color : inherit;
}
}
.themeSelector {
position : absolute;
top : 25px;
right : 0;
z-index : 10;
display : flex;
align-items : center;
justify-content : center;
width : 170px;
height : inherit;
background-color : inherit;
}
}
}
.snippetBarButton {
display : inline-block;
@@ -89,6 +121,7 @@
font-weight : 800;
line-height : @menuHeight;
text-transform : uppercase;
text-wrap : nowrap;
cursor : pointer;
&:hover, &.selected { background-color : #999999; }
i {
@@ -105,7 +138,7 @@
.tooltipLeft('Edit Brew Properties');
}
.snippetGroup {
border-right : 1px solid currentColor;
&:hover {
& > .dropdown { visibility : visible; }
}
@@ -127,11 +160,11 @@
cursor : pointer;
.animate(background-color);
i {
min-width : 25px;
height : 1.2em;
margin-right : 8px;
font-size : 1.2em;
min-width: 25px;
text-align: center;
text-align : center;
& ~ i {
margin-right : 0;
margin-left : 5px;
@@ -164,6 +197,7 @@
}
}
.name { margin-right : auto; }
.disabled { text-decoration : line-through; }
.beta {
align-self : center;
padding : 4px 6px;
@@ -189,4 +223,19 @@
}
}
}
}
}
@container editor (width < 553px) {
.snippetBar {
.editors {
flex : 1;
justify-content : space-between;
border-bottom : 1px solid;
}
.snippets {
flex : 1;
justify-content : space-evenly;
}
.editors > div.history > .dropdown { right : unset; }
}
}

View File

@@ -1,149 +0,0 @@
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const StringArrayEditor = createClass({
displayName : 'StringArrayEditor',
getDefaultProps : function() {
return {
label : '',
values : [],
valuePatterns : null,
validators : [],
placeholder : '',
notes : [],
unique : false,
cannotEdit : [],
onChange : ()=>{}
};
},
getInitialState : function() {
return {
valueContext : !!this.props.values ? this.props.values.map((value)=>({
value,
editing : false
})) : [],
temporaryValue : '',
updateValue : ''
};
},
componentDidUpdate : function(prevProps) {
if(!_.eq(this.props.values, prevProps.values)) {
this.setState({
valueContext : this.props.values ? this.props.values.map((newValue)=>({
value : newValue,
editing : this.state.valueContext.find(({ value })=>value === newValue)?.editing || false
})) : []
});
}
},
handleChange : function(value) {
this.props.onChange({
target : {
value
}
});
},
addValue : function(value){
this.handleChange(_.uniq([...this.props.values, value]));
this.setState({
temporaryValue : ''
});
},
removeValue : function(index){
this.handleChange(this.props.values.filter((_, i)=>i !== index));
},
updateValue : function(value, index){
const valueContext = this.state.valueContext;
valueContext[index].value = value;
valueContext[index].editing = false;
this.handleChange(valueContext.map((context)=>context.value));
this.setState({ valueContext, updateValue: '' });
},
editValue : function(index){
if(!!this.props.cannotEdit && this.props.cannotEdit.includes(this.props.values[index])) {
return;
}
const valueContext = this.state.valueContext.map((context, i)=>{
context.editing = index === i;
return context;
});
this.setState({ valueContext, updateValue: this.props.values[index] });
},
valueIsValid : function(value, index) {
const values = _.clone(this.props.values);
if(index !== undefined) {
values.splice(index, 1);
}
const matchesPatterns = !this.props.valuePatterns || this.props.valuePatterns.some((pattern)=>!!(value || '').match(pattern));
const uniqueIfSet = !this.props.unique || !values.includes(value);
const passesValidators = !this.props.validators || this.props.validators.every((validator)=>validator(value));
return matchesPatterns && uniqueIfSet && passesValidators;
},
handleValueInputKeyDown : function(event, index) {
if(event.key === 'Enter') {
if(this.valueIsValid(event.target.value, index)) {
if(index !== undefined) {
this.updateValue(event.target.value, index);
} else {
this.addValue(event.target.value);
}
}
} else if(event.key === 'Escape') {
this.closeEditInput(index);
}
},
closeEditInput : function(index) {
const valueContext = this.state.valueContext;
valueContext[index].editing = false;
this.setState({ valueContext, updateValue: '' });
},
render : function() {
const valueElements = Object.values(this.state.valueContext).map((context, i)=>context.editing
? <React.Fragment key={i}>
<div className='input-group'>
<input type='text' className={`value ${this.valueIsValid(this.state.updateValue, i) ? '' : 'invalid'}`} autoFocus placeholder={this.props.placeholder}
value={this.state.updateValue}
onKeyDown={(e)=>this.handleValueInputKeyDown(e, i)}
onChange={(e)=>this.setState({ updateValue: e.target.value })}/>
{<div className='icon steel' onClick={(e)=>{ e.stopPropagation(); this.closeEditInput(i); }}><i className='fa fa-undo fa-fw'/></div>}
{this.valueIsValid(this.state.updateValue, i) ? <div className='icon steel' onClick={(e)=>{ e.stopPropagation(); this.updateValue(this.state.updateValue, i); }}><i className='fa fa-check fa-fw'/></div> : null}
</div>
</React.Fragment>
: <div className='badge' key={i} onClick={()=>this.editValue(i)}>{context.value}
{!!this.props.cannotEdit && this.props.cannotEdit.includes(context.value) ? null : <div className='icon steel' onClick={(e)=>{ e.stopPropagation(); this.removeValue(i); }}><i className='fa fa-times fa-fw'/></div>}
</div>
);
return <div className='field'>
<label>{this.props.label}</label>
<div style={{ flex: '1 0' }}>
<div className='list'>
{valueElements}
<div className='input-group'>
<input type='text' className={`value ${this.valueIsValid(this.state.temporaryValue) ? '' : 'invalid'}`} placeholder={this.props.placeholder}
value={this.state.temporaryValue}
onKeyDown={(e)=>this.handleValueInputKeyDown(e)}
onChange={(e)=>this.setState({ temporaryValue: e.target.value })}/>
{this.valueIsValid(this.state.temporaryValue) ? <div className='icon steel' onClick={(e)=>{ e.stopPropagation(); this.addValue(this.state.temporaryValue); }}><i className='fa fa-check fa-fw'/></div> : null}
</div>
</div>
{this.props.notes ? this.props.notes.map((n, index)=><p key={index}><small>{n}</small></p>) : null}
</div>
</div>;
}
});
module.exports = StringArrayEditor;

View File

@@ -0,0 +1,105 @@
require('./tagInput.less');
const React = require('react');
const { useState, useEffect } = React;
const _ = require('lodash');
const TagInput = ({ unique = true, values = [], ...props }) => {
const [tempInputText, setTempInputText] = useState('');
const [tagList, setTagList] = useState(values.map((value) => ({ value, editing: false })));
useEffect(()=>{
handleChange(tagList.map((context)=>context.value))
}, [tagList])
const handleChange = (value)=>{
props.onChange({
target : { value }
})
};
const handleInputKeyDown = ({ evt, value, index, options = {} }) => {
if (_.includes(['Enter', ','], evt.key)) {
evt.preventDefault();
submitTag(evt.target.value, value, index);
if (options.clear) {
setTempInputText('');
}
}
};
const submitTag = (newValue, originalValue, index) => {
setTagList((prevContext) => {
// remove existing tag
if(newValue === null){
return [...prevContext].filter((context, i)=>i !== index);
}
// add new tag
if(originalValue === null){
return [...prevContext, { value: newValue, editing: false }]
}
// update existing tag
return prevContext.map((context, i) => {
if (i === index) {
return { ...context, value: newValue, editing: false };
}
return context;
});
});
};
const editTag = (index) => {
setTagList((prevContext) => {
return prevContext.map((context, i) => {
if (i === index) {
return { ...context, editing: true };
}
return { ...context, editing: false };
});
});
};
const renderReadTag = (context, index) => {
return (
<li key={index}
data-value={context.value}
className='tag'
onClick={() => editTag(index)}>
{context.value}
<button onClick={(evt)=>{evt.stopPropagation(); submitTag(null, context.value, index)}}><i className='fa fa-times fa-fw'/></button>
</li>
);
};
const renderWriteTag = (context, index) => {
return (
<input type='text'
key={index}
defaultValue={context.value}
onKeyDown={(evt) => handleInputKeyDown({evt, value: context.value, index: index})}
autoFocus
/>
);
};
return (
<div className='field'>
<label>{props.label}</label>
<div className='value'>
<ul className='list'>
{tagList.map((context, index) => { return context.editing ? renderWriteTag(context, index) : renderReadTag(context, index); })}
</ul>
<input
type='text'
className='value'
placeholder={props.placeholder}
value={tempInputText}
onChange={(e) => setTempInputText(e.target.value)}
onKeyDown={(evt) => handleInputKeyDown({ evt, value: null, options: { clear: true } })}
/>
</div>
</div>
);
};
module.exports = TagInput;

View File

@@ -10,6 +10,7 @@ const UserPage = require('./pages/userPage/userPage.jsx');
const SharePage = require('./pages/sharePage/sharePage.jsx');
const NewPage = require('./pages/newPage/newPage.jsx');
const ErrorPage = require('./pages/errorPage/errorPage.jsx');
const VaultPage = require('./pages/vaultPage/vaultPage.jsx');
const AccountPage = require('./pages/accountPage/accountPage.jsx');
const WithRoute = (props)=>{
@@ -66,13 +67,15 @@ const Homebrew = createClass({
<Router location={this.props.url}>
<div className='homebrew'>
<Routes>
<Route path='/edit/:id' element={<WithRoute el={EditPage} brew={this.props.brew} />} />
<Route path='/edit/:id' element={<WithRoute el={EditPage} brew={this.props.brew} userThemes={this.props.userThemes}/>} />
<Route path='/share/:id' element={<WithRoute el={SharePage} brew={this.props.brew} />} />
<Route path='/new/:id' element={<WithRoute el={NewPage} brew={this.props.brew} />} />
<Route path='/new' element={<WithRoute el={NewPage}/>} />
<Route path='/new/:id' element={<WithRoute el={NewPage} brew={this.props.brew} userThemes={this.props.userThemes}/>} />
<Route path='/new' element={<WithRoute el={NewPage} userThemes={this.props.userThemes}/> } />
<Route path='/user/:username' element={<WithRoute el={UserPage} brews={this.props.brews} />} />
<Route path='/changelog' element={<WithRoute el={SharePage} brew={this.props.brew} />} />
<Route path='/faq' element={<WithRoute el={SharePage} brew={this.props.brew} />} />
<Route path='/vault' element={<WithRoute el={VaultPage}/>}/>
<Route path='/changelog' element={<WithRoute el={SharePage} brew={this.props.brew} disableMeta={true} />} />
<Route path='/faq' element={<WithRoute el={SharePage} brew={this.props.brew} disableMeta={true} />} />
<Route path='/migrate' element={<WithRoute el={SharePage} brew={this.props.brew} disableMeta={true} />} />
<Route path='/account' element={<WithRoute el={AccountPage} brew={this.props.brew} accountDetails={this.props.brew.accountDetails} />} />
<Route path='/legacy' element={<WithRoute el={HomePage} brew={this.props.brew} />} />
<Route path='/error' element={<WithRoute el={ErrorPage} brew={this.props.brew} />} />

View File

@@ -1,34 +0,0 @@
const React = require('react');
const createClass = require('create-react-class');
const cx = require('classnames');
const Nav = require('naturalcrit/nav/nav.jsx');
const MAX_TITLE_LENGTH = 50;
const EditTitle = createClass({
displayName : 'EditTitleNavItem',
getDefaultProps : function() {
return {
title : '',
onChange : function(){}
};
},
handleChange : function(e){
if(e.target.value.length > MAX_TITLE_LENGTH) return;
this.props.onChange(e.target.value);
},
render : function(){
return <Nav.item className='editTitle'>
<input placeholder='Brew Title' type='text' value={this.props.title} onChange={this.handleChange} />
<div className={cx('charCount', { 'max': this.props.title.length >= MAX_TITLE_LENGTH })}>
{this.props.title.length}/{MAX_TITLE_LENGTH}
</div>
</Nav.item>;
},
});
module.exports = EditTitle;

View File

@@ -104,6 +104,18 @@ const ErrorNavItem = createClass({
</Nav.item>;
}
if(HBErrorCode === '09') {
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
Oops!
<div className='errorContainer' onClick={clearError}>
Looks like there was a problem retreiving
the theme, or a theme that it inherits,
for this brew. Verify that brew <a className='lowercase' target='_blank' rel='noopener noreferrer' href={`/share/${response.body.brewId}`}>
{response.body.brewId}</a> still exists!
</div>
</Nav.item>;
}
return <Nav.item className='save error' icon='fas fa-exclamation-triangle'>
Oops!
<div className='errorContainer'>

View File

@@ -21,6 +21,9 @@
font-size : 10px;
font-weight : 800;
text-transform : uppercase;
.lowercase {
text-transform : none;
}
a{
color : @teal;
}

View File

@@ -1,6 +1,7 @@
@import 'naturalcrit/styles/colors.less';
@navbarHeight : 28px;
@viewerToolsHeight : 32px;
@keyframes pinkColoring {
0% { color : pink; }
@@ -24,16 +25,20 @@
.homebrew nav {
background-color : #333333;
.navContent {
position : relative;
z-index : 2;
display : flex;
justify-content : space-between;
}
position : relative;
z-index : 2;
display : flex;
justify-content : space-between;
.navSection {
display : flex;
align-items : center;
&:last-child .navItem { border-left : 1px solid #666666; }
&:has(.brewTitle) {
flex-grow : 1;
min-width : 300px;
}
}
// "NaturalCrit" logo
.navLogo {
@@ -68,6 +73,10 @@
.navItem {
#backgroundColorsHover;
.animate(background-color);
display : flex;
align-items : center;
justify-content : center;
height : 100%;
padding : 8px 12px;
font-size : 10px;
font-weight : 800;
@@ -93,39 +102,20 @@
animation-duration : 2s;
}
}
&.editTitle { // this is not needed at all currently - you used to be able to edit the title via the navbar.
padding : 2px 12px;
input {
width : 250px;
padding : 2px;
margin : 0;
font-family : 'Open Sans', sans-serif;
font-size : 12px;
font-weight : 800;
color : white;
text-align : center;
background-color : transparent;
border : 1px solid @blue;
outline : none;
}
.charCount {
display : inline-block;
margin-left : 8px;
color : #666666;
text-align : right;
vertical-align : bottom;
&.max { color : @red; }
}
}
&.brewTitle {
flex-grow : 1;
display : block;
width : 100%;
overflow : hidden;
font-size : 12px;
font-weight : 800;
color : white;
text-align : center;
text-transform : initial;
background-color : transparent;
text-overflow : ellipsis;
text-transform : initial;
white-space : nowrap;
background-color : transparent;
}
// "The Homebrewery" logo
&.homebrewLogo {
.animate(color);
@@ -239,23 +229,25 @@
}
.navDropdownContainer {
position : relative;
height : 100%;
.navDropdown {
position: absolute;
top: 28px;
right: 0px;
z-index: 10000;
width: max-content;
min-width:100%;
max-height: calc(100vh - 28px);
overflow: hidden auto;
display: flex;
flex-direction: column;
align-items: flex-end;
position : absolute;
//top: 28px;
right : 0px;
z-index : 10000;
display : flex;
flex-direction : column;
align-items : flex-end;
width : max-content;
min-width : 100%;
max-height : calc(100vh - 28px);
overflow : hidden auto;
.navItem {
position : relative;
display : flex;
justify-content : space-between;
align-items : center;
justify-content : space-between;
width : 100%;
border : 1px solid #888888;
border-bottom : 0;
@@ -277,10 +269,10 @@
overflow : hidden auto;
color : white;
text-decoration : none;
background-color : #333333;
border-top : 1px solid #888888;
scrollbar-color : #666666 #333333;
scrollbar-width : thin;
background-color : #333333;
border-top : 1px solid #888888;
.clear {
position : absolute;
top : 50%;

View File

@@ -36,7 +36,7 @@ const RecentItems = createClass({
//== Add current brew to appropriate recent items list (depending on storageKey) ==//
if(this.props.storageKey == 'edit'){
let editId = this.props.brew.editId;
if(this.props.brew.googleId){
if(this.props.brew.googleId && !this.props.brew.stubbed){
editId = `${this.props.brew.googleId}${this.props.brew.editId}`;
}
edited = _.filter(edited, (brew)=>{
@@ -51,7 +51,7 @@ const RecentItems = createClass({
}
if(this.props.storageKey == 'view'){
let shareId = this.props.brew.shareId;
if(this.props.brew.googleId){
if(this.props.brew.googleId && !this.props.brew.stubbed){
shareId = `${this.props.brew.googleId}${this.props.brew.shareId}`;
}
viewed = _.filter(viewed, (brew)=>{
@@ -83,7 +83,7 @@ const RecentItems = createClass({
let edited = JSON.parse(localStorage.getItem(EDIT_KEY) || '[]');
if(this.props.storageKey == 'edit') {
let prevEditId = prevProps.brew.editId;
if(prevProps.brew.googleId){
if(prevProps.brew.googleId && !this.props.brew.stubbed){
prevEditId = `${prevProps.brew.googleId}${prevProps.brew.editId}`;
}
@@ -91,7 +91,7 @@ const RecentItems = createClass({
return brew.id !== prevEditId;
});
let editId = this.props.brew.editId;
if(this.props.brew.googleId){
if(this.props.brew.googleId && !this.props.brew.stubbed){
editId = `${this.props.brew.googleId}${this.props.brew.editId}`;
}
edited.unshift({

View File

@@ -1,44 +0,0 @@
const React = require('react');
const createClass = require('create-react-class');
const Nav = require('naturalcrit/nav/nav.jsx');
const MAIN_URL = 'https://www.reddit.com/r/UnearthedArcana/submit?selftext=true';
const RedditShare = createClass({
displayName : 'RedditShareNavItem',
getDefaultProps : function() {
return {
brew : {
title : '',
sharedId : '',
text : ''
}
};
},
getText : function(){
},
handleClick : function(){
const url = [
MAIN_URL,
`title=${encodeURIComponent(this.props.brew.title ? this.props.brew.title : 'Check out my brew!')}`,
`text=${encodeURIComponent(this.props.brew.text)}`
].join('&');
window.open(url, '_blank');
},
render : function(){
return <Nav.item icon='fa-reddit-alien' color='red' onClick={this.handleClick}>
share on reddit
</Nav.item>;
},
});
module.exports = RedditShare;

View File

@@ -0,0 +1,17 @@
const React = require('react');
const Nav = require('naturalcrit/nav/nav.jsx');
module.exports = function (props) {
return (
<Nav.item
color='purple'
icon='fas fa-dungeon'
href='/vault'
newTab={false}
rel='noopener noreferrer'
>
Vault
</Nav.item>
);
};

View File

@@ -2,7 +2,7 @@ require('./brewItem.less');
const React = require('react');
const createClass = require('create-react-class');
const moment = require('moment');
const request = require('../../../../utils/request-middleware.js');
import request from '../../../../utils/request-middleware.js';
const googleDriveIcon = require('../../../../googleDrive.svg');
const homebreweryIcon = require('../../../../thumbnail.png');
@@ -19,7 +19,8 @@ const BrewItem = createClass({
stubbed : true
},
updateListFilter : ()=>{},
reportError : ()=>{}
reportError : ()=>{},
renderStorage : true
};
},
@@ -95,6 +96,7 @@ const BrewItem = createClass({
},
renderStorageIcon : function(){
if(!this.props.renderStorage) return;
if(this.props.brew.googleId) {
return <span title={this.props.brew.webViewLink ? 'Your Google Drive Storage': 'Another User\'s Google Drive Storage'}>
<a href={this.props.brew.webViewLink} target='_blank'>
@@ -142,10 +144,14 @@ const BrewItem = createClass({
}
<span title={`Authors:\n${brew.authors?.join('\n')}`}>
<i className='fas fa-user'/> {brew.authors?.map((author, index)=>(
<>
<a key={index} href={`/user/${author}`}>{author}</a>
{index < brew.authors.length - 1 && ', '}
</>))}
<React.Fragment key={index}>
{author === 'hidden'
? <span title="Username contained an email address; hidden to protect user's privacy">{author}</span>
: <a href={`/user/${author}`}>{author}</a>
}
{index < brew.authors.length - 1 && ', '}
</React.Fragment>
))}
</span>
<br />
<span title={`Last viewed: ${moment(brew.lastViewed).local().format(dateFormatString)}`}>

View File

@@ -1,9 +1,10 @@
/* eslint-disable max-lines */
require('./editPage.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const request = require('../../utils/request-middleware.js');
const createClass = require('create-react-class');
import request from '../../utils/request-middleware.js';
const { Meta } = require('vitreum/headtags');
const Nav = require('naturalcrit/nav/nav.jsx');
@@ -15,6 +16,7 @@ const PrintNavItem = require('../../navbar/print.navitem.jsx');
const ErrorNavItem = require('../../navbar/error-navitem.jsx');
const Account = require('../../navbar/account.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const VaultNavItem = require('../../navbar/vault.navitem.jsx');
const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
const Editor = require('../../editor/editor.jsx');
@@ -22,14 +24,16 @@ const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
const LockNotification = require('./lockNotification/lockNotification.jsx');
const Markdown = require('naturalcrit/markdown.js');
import Markdown from 'naturalcrit/markdown.js';
const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js');
const { printCurrentBrew } = require('../../../../shared/helpers.js');
const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpers.js');
import { updateHistory, versionHistoryGarbageCollection } from '../../utils/versionHistory.js';
const googleDriveIcon = require('../../googleDrive.svg');
const SAVE_TIMEOUT = 3000;
const SAVE_TIMEOUT = 10000;
const EditPage = createClass({
displayName : 'EditPage',
@@ -41,21 +45,24 @@ const EditPage = createClass({
getInitialState : function() {
return {
brew : this.props.brew,
isSaving : false,
isPending : false,
alertTrashedGoogleBrew : this.props.brew.trashed,
alertLoginToTransfer : false,
saveGoogle : this.props.brew.googleId ? true : false,
confirmGoogleTransfer : false,
error : null,
htmlErrors : Markdown.validate(this.props.brew.text),
url : '',
autoSave : true,
autoSaveWarning : false,
unsavedTime : new Date(),
currentEditorPage : 0,
displayLockMessage : this.props.brew.lock || false
brew : this.props.brew,
isSaving : false,
isPending : false,
alertTrashedGoogleBrew : this.props.brew.trashed,
alertLoginToTransfer : false,
saveGoogle : this.props.brew.googleId ? true : false,
confirmGoogleTransfer : false,
error : null,
htmlErrors : Markdown.validate(this.props.brew.text),
url : '',
autoSave : true,
autoSaveWarning : false,
unsavedTime : new Date(),
currentEditorViewPageNum : 1,
currentEditorCursorPageNum : 1,
currentBrewRendererPageNum : 1,
displayLockMessage : this.props.brew.lock || false,
themeBundle : {}
};
},
@@ -87,6 +94,8 @@ const EditPage = createClass({
htmlErrors : Markdown.validate(prevState.brew.text)
}));
fetchThemeBundle(this, this.props.brew.renderer, this.props.brew.theme);
document.addEventListener('keydown', this.handleControlKeys);
},
componentWillUnmount : function() {
@@ -110,16 +119,27 @@ const EditPage = createClass({
this.editor.current.update();
},
handleEditorViewPageChange : function(pageNumber){
this.setState({ currentEditorViewPageNum: pageNumber });
},
handleEditorCursorPageChange : function(pageNumber){
this.setState({ currentEditorCursorPageNum: pageNumber });
},
handleBrewRendererPageChange : function(pageNumber){
this.setState({ currentBrewRendererPageNum: pageNumber });
},
handleTextChange : function(text){
//If there are errors, run the validator on every change to give quick feedback
let htmlErrors = this.state.htmlErrors;
if(htmlErrors.length) htmlErrors = Markdown.validate(text);
this.setState((prevState)=>({
brew : { ...prevState.brew, text: text },
isPending : true,
htmlErrors : htmlErrors,
currentEditorPage : this.editor.current.getCurrentPage() - 1 //Offset index since Marked starts pages at 0
brew : { ...prevState.brew, text: text },
isPending : true,
htmlErrors : htmlErrors,
}), ()=>{if(this.state.autoSave) this.trySave();});
},
@@ -130,7 +150,10 @@ const EditPage = createClass({
}), ()=>{if(this.state.autoSave) this.trySave();});
},
handleMetaChange : function(metadata){
handleMetaChange : function(metadata, field=undefined){
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
fetchThemeBundle(this, metadata.renderer, metadata.theme);
this.setState((prevState)=>({
brew : {
...prevState.brew,
@@ -138,13 +161,22 @@ const EditPage = createClass({
},
isPending : true,
}), ()=>{if(this.state.autoSave) this.trySave();});
},
hasChanges : function(){
return !_.isEqual(this.state.brew, this.savedBrew);
},
updateBrew : function(newData){
this.setState((prevState)=>({
brew : {
...prevState.brew,
style : newData.style,
text : newData.text
}
}));
},
trySave : function(immediate=false){
if(!this.debounceSave) this.debounceSave = _.debounce(this.save, SAVE_TIMEOUT);
if(this.hasChanges()){
@@ -197,6 +229,9 @@ const EditPage = createClass({
htmlErrors : Markdown.validate(prevState.brew.text)
}));
await updateHistory(this.state.brew).catch(console.error);
await versionHistoryGarbageCollection().catch(console.error);
const transfer = this.state.saveGoogle == _.isNil(this.state.brew.googleId);
const brew = this.state.brew;
@@ -383,6 +418,7 @@ const EditPage = createClass({
</Nav.item>
</Nav.dropdown>
<PrintNavItem />
<VaultNavItem />
<RecentNavItem brew={this.state.brew} storageKey='edit' />
<Account />
</Nav.section>
@@ -395,29 +431,41 @@ const EditPage = createClass({
<Meta name='robots' content='noindex, nofollow' />
{this.renderNavbar()}
<div className='content'>
{this.props.brew.lock && <LockNotification shareId={this.props.brew.shareId} message={this.props.brew.lock.editMessage} />}
<SplitPane onDragFinish={this.handleSplitMove}>
<Editor
ref={this.editor}
brew={this.state.brew}
onTextChange={this.handleTextChange}
onStyleChange={this.handleStyleChange}
onMetaChange={this.handleMetaChange}
reportError={this.errorReported}
renderer={this.state.brew.renderer}
/>
<BrewRenderer
text={this.state.brew.text}
style={this.state.brew.style}
renderer={this.state.brew.renderer}
theme={this.state.brew.theme}
errors={this.state.htmlErrors}
lang={this.state.brew.lang}
currentEditorPage={this.state.currentEditorPage}
allowPrint={true}
/>
</SplitPane>
{this.props.brew.lock && <LockNotification shareId={this.props.brew.shareId} message={this.props.brew.lock.editMessage} />}
<div className="content">
<SplitPane onDragFinish={this.handleSplitMove}>
<Editor
ref={this.editor}
brew={this.state.brew}
onTextChange={this.handleTextChange}
onStyleChange={this.handleStyleChange}
onMetaChange={this.handleMetaChange}
reportError={this.errorReported}
renderer={this.state.brew.renderer}
userThemes={this.props.userThemes}
snippetBundle={this.state.themeBundle.snippets}
updateBrew={this.updateBrew}
onCursorPageChange={this.handleEditorCursorPageChange}
onViewPageChange={this.handleEditorViewPageChange}
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
/>
<BrewRenderer
text={this.state.brew.text}
style={this.state.brew.style}
renderer={this.state.brew.renderer}
theme={this.state.brew.theme}
themeBundle={this.state.themeBundle}
errors={this.state.htmlErrors}
lang={this.state.brew.lang}
onPageChange={this.handleBrewRendererPageChange}
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
allowPrint={true}
/>
</SplitPane>
</div>
</div>;
}

View File

@@ -1,7 +1,7 @@
require('./errorPage.less');
const React = require('react');
const UIPage = require('../basePages/uiPage/uiPage.jsx');
const Markdown = require('../../../../shared/naturalcrit/markdown.js');
import Markdown from '../../../../shared/naturalcrit/markdown.js';
const ErrorIndex = require('./errors/errorIndex.js');
const ErrorPage = ({ brew })=>{

View File

@@ -2,6 +2,9 @@ const dedent = require('dedent-tabs').default;
const loginUrl = 'https://www.naturalcrit.com/login';
//001-050 : Brew errors
//050-100 : Other pages errors
const errorIndex = (props)=>{
return {
// Default catch all
@@ -136,8 +139,29 @@ const errorIndex = (props)=>{
**Brew ID:** ${props.brew.brewId}`,
// Theme load error
'09' : dedent`
## No Homebrewery theme document could be found.
The server could not locate the Homebrewery document. It was likely deleted by
its owner.
:
**Requested access:** ${props.brew.accessType}
**Brew ID:** ${props.brew.brewId}`,
//account page when account is not defined
'50' : dedent`
## You are not signed in
You are trying to access the account page, but are not signed in to an account.
Please login or signup at our [login page](https://www.naturalcrit.com/login?redirect=https://homebrewery.naturalcrit.com/account).`,
// Brew locked by Administrators error
'100' : dedent`
'51' : dedent`
## This brew has been locked.
Only an author may request that this lock is removed.
@@ -147,7 +171,17 @@ const errorIndex = (props)=>{
**Brew ID:** ${props.brew.brewId}
**Brew Title:** ${props.brew.brewTitle}`,
// ####### Admin page error #######
'52': dedent`
## Access Denied
You need to provide correct administrator credentials to access this page.`,
'90' : dedent` An unexpected error occurred while looking for these brews.
Try again in a few minutes.`,
'91' : dedent` An unexpected error occurred while trying to get the total of brews.`,
};
};
module.exports = errorIndex;
module.exports = errorIndex;

View File

@@ -1,19 +1,19 @@
require('./homePage.less');
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const cx = require('classnames');
const request = require('../../utils/request-middleware.js');
import request from '../../utils/request-middleware.js';
const { Meta } = require('vitreum/headtags');
const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
const NewBrewItem = require('../../navbar/newbrew.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const VaultNavItem = require('../../navbar/vault.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const AccountNavItem = require('../../navbar/account.navitem.jsx');
const ErrorNavItem = require('../../navbar/error-navitem.jsx');
const { fetchThemeBundle } = require('../../../../shared/helpers.js');
const SplitPane = require('naturalcrit/splitPane/splitPane.jsx');
const Editor = require('../../editor/editor.jsx');
@@ -31,15 +31,22 @@ const HomePage = createClass({
},
getInitialState : function() {
return {
brew : this.props.brew,
welcomeText : this.props.brew.text,
error : undefined,
currentEditorPage : 0
brew : this.props.brew,
welcomeText : this.props.brew.text,
error : undefined,
currentEditorViewPageNum : 1,
currentEditorCursorPageNum : 1,
currentBrewRendererPageNum : 1,
themeBundle : {}
};
},
editor : React.createRef(null),
componentDidMount : function() {
fetchThemeBundle(this, this.props.brew.renderer, this.props.brew.theme);
},
handleSave : function(){
request.post('/api')
.send(this.state.brew)
@@ -55,10 +62,22 @@ const HomePage = createClass({
handleSplitMove : function(){
this.editor.current.update();
},
handleEditorViewPageChange : function(pageNumber){
this.setState({ currentEditorViewPageNum: pageNumber });
},
handleEditorCursorPageChange : function(pageNumber){
this.setState({ currentEditorCursorPageNum: pageNumber });
},
handleBrewRendererPageChange : function(pageNumber){
this.setState({ currentBrewRendererPageNum: pageNumber });
},
handleTextChange : function(text){
this.setState((prevState)=>({
brew : { ...prevState.brew, text: text },
currentEditorPage : this.editor.current.getCurrentPage() - 1 //Offset index since Marked starts pages at 0
brew : { ...prevState.brew, text: text },
}));
},
renderNavbar : function(){
@@ -70,6 +89,7 @@ const HomePage = createClass({
}
<NewBrewItem />
<HelpNavItem />
<VaultNavItem />
<RecentNavItem />
<AccountNavItem />
</Nav.section>
@@ -80,25 +100,33 @@ const HomePage = createClass({
return <div className='homePage sitePage'>
<Meta name='google-site-verification' content='NwnAQSSJZzAT7N-p5MY6ydQ7Njm67dtbu73ZSyE5Fy4' />
{this.renderNavbar()}
<div className='content'>
<SplitPane onDragFinish={this.handleSplitMove}>
<Editor
ref={this.editor}
brew={this.state.brew}
onTextChange={this.handleTextChange}
renderer={this.state.brew.renderer}
showEditButtons={false}
/>
<BrewRenderer
text={this.state.brew.text}
style={this.state.brew.style}
renderer={this.state.brew.renderer}
currentEditorPage={this.state.currentEditorPage}
/>
</SplitPane>
<div className="content">
<SplitPane onDragFinish={this.handleSplitMove}>
<Editor
ref={this.editor}
brew={this.state.brew}
onTextChange={this.handleTextChange}
renderer={this.state.brew.renderer}
showEditButtons={false}
snippetBundle={this.state.themeBundle.snippets}
onCursorPageChange={this.handleEditorCursorPageChange}
onViewPageChange={this.handleEditorViewPageChange}
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
/>
<BrewRenderer
text={this.state.brew.text}
style={this.state.brew.style}
renderer={this.state.brew.renderer}
onPageChange={this.handleBrewRendererPageChange}
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
themeBundle={this.state.themeBundle}
/>
</SplitPane>
</div>
<div className={cx('floatingSaveButton', { show: this.state.welcomeText != this.state.brew.text })} onClick={this.handleSave}>
Save current <i className='fas fa-save' />
</div>

View File

@@ -91,13 +91,6 @@ If you are looking for more 5e Homebrew resources check out [r/UnearthedArcana](
\page
## Markdown+
The Homebrewery aims to make homebrewing as simple as possible, providing a live editor with Markdown syntax that is more human-readable and faster to write with than raw HTML.

View File

@@ -2,9 +2,9 @@
require('./newPage.less');
const React = require('react');
const createClass = require('create-react-class');
const request = require('../../utils/request-middleware.js');
import request from '../../utils/request-middleware.js';
const Markdown = require('naturalcrit/markdown.js');
import Markdown from 'naturalcrit/markdown.js';
const Nav = require('naturalcrit/nav/nav.jsx');
const PrintNavItem = require('../../navbar/print.navitem.jsx');
@@ -19,7 +19,7 @@ const Editor = require('../../editor/editor.jsx');
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
const { DEFAULT_BREW } = require('../../../../server/brewDefaults.js');
const { printCurrentBrew } = require('../../../../shared/helpers.js');
const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpers.js');
const BREWKEY = 'homebrewery-new';
const STYLEKEY = 'homebrewery-new-style';
@@ -39,12 +39,15 @@ const NewPage = createClass({
const brew = this.props.brew;
return {
brew : brew,
isSaving : false,
saveGoogle : (global.account && global.account.googleId ? true : false),
error : null,
htmlErrors : Markdown.validate(brew.text),
currentEditorPage : 0
brew : brew,
isSaving : false,
saveGoogle : (global.account && global.account.googleId ? true : false),
error : null,
htmlErrors : Markdown.validate(brew.text),
currentEditorViewPageNum : 1,
currentEditorCursorPageNum : 1,
currentBrewRendererPageNum : 1,
themeBundle : {}
};
},
@@ -77,10 +80,15 @@ const NewPage = createClass({
saveGoogle : (saveStorage == 'GOOGLE-DRIVE' && this.state.saveGoogle)
});
fetchThemeBundle(this, this.props.brew.renderer, this.props.brew.theme);
localStorage.setItem(BREWKEY, brew.text);
if(brew.style)
localStorage.setItem(STYLEKEY, brew.style);
localStorage.setItem(METAKEY, JSON.stringify({ 'renderer': brew.renderer, 'theme': brew.theme, 'lang': brew.lang }));
if(window.location.pathname != '/new') {
window.history.replaceState({}, window.location.title, '/new/');
}
},
componentWillUnmount : function() {
document.removeEventListener('keydown', this.handleControlKeys);
@@ -102,15 +110,26 @@ const NewPage = createClass({
this.editor.current.update();
},
handleEditorViewPageChange : function(pageNumber){
this.setState({ currentEditorViewPageNum: pageNumber });
},
handleEditorCursorPageChange : function(pageNumber){
this.setState({ currentEditorCursorPageNum: pageNumber });
},
handleBrewRendererPageChange : function(pageNumber){
this.setState({ currentBrewRendererPageNum: pageNumber });
},
handleTextChange : function(text){
//If there are errors, run the validator on every change to give quick feedback
let htmlErrors = this.state.htmlErrors;
if(htmlErrors.length) htmlErrors = Markdown.validate(text);
this.setState((prevState)=>({
brew : { ...prevState.brew, text: text },
htmlErrors : htmlErrors,
currentEditorPage : this.editor.current.getCurrentPage() - 1 //Offset index since Marked starts pages at 0
brew : { ...prevState.brew, text: text },
htmlErrors : htmlErrors,
}));
localStorage.setItem(BREWKEY, text);
},
@@ -122,7 +141,10 @@ const NewPage = createClass({
localStorage.setItem(STYLEKEY, style);
},
handleMetaChange : function(metadata){
handleMetaChange : function(metadata, field=undefined){
if(field == 'theme' || field == 'renderer') // Fetch theme bundle only if theme or renderer was changed
fetchThemeBundle(this, metadata.renderer, metadata.theme);
this.setState((prevState)=>({
brew : { ...prevState.brew, ...metadata },
}), ()=>{
@@ -142,8 +164,6 @@ const NewPage = createClass({
isSaving : true
});
console.log('saving new brew');
let brew = this.state.brew;
// Split out CSS to Style if CSS codefence exists
if(brew.text.startsWith('```css') && brew.text.indexOf('```\n\n') > 0) {
@@ -153,12 +173,10 @@ const NewPage = createClass({
}
brew.pageCount=((brew.renderer=='legacy' ? brew.text.match(/\\page/g) : brew.text.match(/^\\page$/gm)) || []).length + 1;
const res = await request
.post(`/api${this.state.saveGoogle ? '?saveToGoogle=true' : ''}`)
.send(brew)
.catch((err)=>{
console.log(err);
this.setState({ isSaving: false, error: err });
});
if(!res) return;
@@ -205,27 +223,38 @@ const NewPage = createClass({
render : function(){
return <div className='newPage sitePage'>
{this.renderNavbar()}
<div className='content'>
<SplitPane onDragFinish={this.handleSplitMove}>
<Editor
ref={this.editor}
brew={this.state.brew}
onTextChange={this.handleTextChange}
onStyleChange={this.handleStyleChange}
onMetaChange={this.handleMetaChange}
renderer={this.state.brew.renderer}
/>
<BrewRenderer
text={this.state.brew.text}
style={this.state.brew.style}
renderer={this.state.brew.renderer}
theme={this.state.brew.theme}
errors={this.state.htmlErrors}
lang={this.state.brew.lang}
currentEditorPage={this.state.currentEditorPage}
allowPrint={true}
/>
</SplitPane>
<div className="content">
<SplitPane onDragFinish={this.handleSplitMove}>
<Editor
ref={this.editor}
brew={this.state.brew}
onTextChange={this.handleTextChange}
onStyleChange={this.handleStyleChange}
onMetaChange={this.handleMetaChange}
renderer={this.state.brew.renderer}
userThemes={this.props.userThemes}
snippetBundle={this.state.themeBundle.snippets}
onCursorPageChange={this.handleEditorCursorPageChange}
onViewPageChange={this.handleEditorViewPageChange}
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
/>
<BrewRenderer
text={this.state.brew.text}
style={this.state.brew.style}
renderer={this.state.brew.renderer}
theme={this.state.brew.theme}
themeBundle={this.state.themeBundle}
errors={this.state.htmlErrors}
lang={this.state.brew.lang}
onPageChange={this.handleBrewRendererPageChange}
currentEditorViewPageNum={this.state.currentEditorViewPageNum}
currentEditorCursorPageNum={this.state.currentEditorCursorPageNum}
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
allowPrint={true}
/>
</SplitPane>
</div>
</div>;
}

View File

@@ -8,28 +8,43 @@ const Navbar = require('../../navbar/navbar.jsx');
const MetadataNav = require('../../navbar/metadata.navitem.jsx');
const PrintNavItem = require('../../navbar/print.navitem.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const VaultNavItem = require('../../navbar/vault.navitem.jsx');
const Account = require('../../navbar/account.navitem.jsx');
const BrewRenderer = require('../../brewRenderer/brewRenderer.jsx');
const { DEFAULT_BREW_LOAD } = require('../../../../server/brewDefaults.js');
const { printCurrentBrew } = require('../../../../shared/helpers.js');
const { printCurrentBrew, fetchThemeBundle } = require('../../../../shared/helpers.js');
const SharePage = createClass({
displayName : 'SharePage',
getDefaultProps : function() {
return {
brew : DEFAULT_BREW_LOAD
brew : DEFAULT_BREW_LOAD,
disableMeta : false
};
},
getInitialState : function() {
return {
themeBundle : {},
currentBrewRendererPageNum : 1
};
},
componentDidMount : function() {
document.addEventListener('keydown', this.handleControlKeys);
fetchThemeBundle(this, this.props.brew.renderer, this.props.brew.theme);
},
componentWillUnmount : function() {
document.removeEventListener('keydown', this.handleControlKeys);
},
handleBrewRendererPageChange : function(pageNumber){
this.setState({ currentBrewRendererPageNum: pageNumber });
},
handleControlKeys : function(e){
if(!(e.ctrlKey || e.metaKey)) return;
const P_KEY = 80;
@@ -60,13 +75,21 @@ const SharePage = createClass({
},
render : function(){
const titleStyle = this.props.disableMeta ? { cursor: 'default' } : {};
const titleEl = <Nav.item className='brewTitle' style={titleStyle}>{this.props.brew.title}</Nav.item>;
return <div className='sharePage sitePage'>
<Meta name='robots' content='noindex, nofollow' />
<Navbar>
<Nav.section className='titleSection'>
<MetadataNav brew={this.props.brew}>
<Nav.item className='brewTitle'>{this.props.brew.title}</Nav.item>
</MetadataNav>
{
this.props.disableMeta ?
titleEl
:
<MetadataNav brew={this.props.brew}>
{titleEl}
</MetadataNav>
}
</Nav.section>
<Nav.section>
@@ -88,6 +111,7 @@ const SharePage = createClass({
</Nav.item>
</Nav.dropdown>
</>}
<VaultNavItem/>
<RecentNavItem brew={this.props.brew} storageKey='view' />
<Account />
</Nav.section>
@@ -97,8 +121,12 @@ const SharePage = createClass({
<BrewRenderer
text={this.props.brew.text}
style={this.props.brew.style}
lang={this.props.brew.lang}
renderer={this.props.brew.renderer}
theme={this.props.brew.theme}
themeBundle={this.state.themeBundle}
onPageChange={this.handleBrewRendererPageChange}
currentBrewRendererPageNum={this.state.currentBrewRendererPageNum}
allowPrint={true}
/>
</div>

View File

@@ -1,5 +1,5 @@
.sharePage{
.navContent .navSection.titleSection {
nav .navSection.titleSection {
flex-grow: 1;
justify-content: center;
}

View File

@@ -1,80 +1,60 @@
const React = require('react');
const createClass = require('create-react-class');
const _ = require('lodash');
const { useState } = React;
const _ = require('lodash');
const ListPage = require('../basePages/listPage/listPage.jsx');
const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const Account = require('../../navbar/account.navitem.jsx');
const NewBrew = require('../../navbar/newbrew.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const ErrorNavItem = require('../../navbar/error-navitem.jsx');
const VaultNavitem = require('../../navbar/vault.navitem.jsx');
const UserPage = createClass({
displayName : 'UserPage',
getDefaultProps : function() {
return {
username : '',
brews : [],
query : '',
error : null
};
},
getInitialState : function() {
const usernameWithS = this.props.username + (this.props.username.endsWith('s') ? `` : `s`);
const UserPage = (props)=>{
props = {
username : '',
brews : [],
query : '',
...props
};
const brews = _.groupBy(this.props.brews, (brew)=>{
return (brew.published ? 'published' : 'private');
});
const [error, setError] = useState(null);
const brewCollection = [
{
title : `${usernameWithS} published brews`,
class : 'published',
brews : brews.published
}
];
if(this.props.username == global.account?.username){
brewCollection.push(
{
title : `${usernameWithS} unpublished brews`,
class : 'unpublished',
brews : brews.private
}
);
}
const usernameWithS = props.username + (props.username.endsWith('s') ? `` : `s`);
const groupedBrews = _.groupBy(props.brews, (brew)=>brew.published ? 'published' : 'private');
return {
brewCollection : brewCollection
};
},
errorReported : function(error) {
this.setState({
error
});
},
const brewCollection = [
{
title : `${usernameWithS} published brews`,
class : 'published',
brews : groupedBrews.published || []
},
...(props.username === global.account?.username ? [{
title : `${usernameWithS} unpublished brews`,
class : 'unpublished',
brews : groupedBrews.private || []
}] : [])
];
navItems : function() {
return <Navbar>
const navItems = (
<Navbar>
<Nav.section>
{this.state.error ?
<ErrorNavItem error={this.state.error} parent={this}></ErrorNavItem> :
null
}
{error && (<ErrorNavItem error={error} parent={null}></ErrorNavItem>)}
<NewBrew />
<HelpNavItem />
<VaultNavitem />
<RecentNavItem />
<Account />
</Nav.section>
</Navbar>;
},
</Navbar>
);
render : function(){
return <ListPage brewCollection={this.state.brewCollection} navItems={this.navItems()} query={this.props.query} reportError={this.errorReported}></ListPage>;
}
});
return (
<ListPage brewCollection={brewCollection} navItems={navItems} query={props.query} reportError={(err)=>setError(err)} />
);
};
module.exports = UserPage;

View File

@@ -0,0 +1,431 @@
/*eslint max-lines: ["warn", {"max": 400, "skipBlankLines": true, "skipComments": true}]*/
/*eslint max-params:["warn", { max: 10 }], */
require('./vaultPage.less');
const React = require('react');
const { useState, useEffect, useRef } = React;
const Nav = require('naturalcrit/nav/nav.jsx');
const Navbar = require('../../navbar/navbar.jsx');
const RecentNavItem = require('../../navbar/recent.navitem.jsx').both;
const Account = require('../../navbar/account.navitem.jsx');
const NewBrew = require('../../navbar/newbrew.navitem.jsx');
const HelpNavItem = require('../../navbar/help.navitem.jsx');
const BrewItem = require('../basePages/listPage/brewItem/brewItem.jsx');
const SplitPane = require('../../../../shared/naturalcrit/splitPane/splitPane.jsx');
const ErrorIndex = require('../errorPage/errors/errorIndex.js');
import request from '../../utils/request-middleware.js';
const VaultPage = (props)=>{
const [pageState, setPageState] = useState(parseInt(props.query.page) || 1);
const [sortState, setSort] = useState(props.query.sort || 'title');
const [dirState, setdir] = useState(props.query.dir || 'asc');
//Response state
const [brewCollection, setBrewCollection] = useState(null);
const [totalBrews, setTotalBrews] = useState(null);
const [searching, setSearching] = useState(false);
const [error, setError] = useState(null);
const titleRef = useRef(null);
const authorRef = useRef(null);
const countRef = useRef(null);
const v3Ref = useRef(null);
const legacyRef = useRef(null);
const submitButtonRef = useRef(null);
useEffect(()=>{
disableSubmitIfFormInvalid();
loadPage(pageState, true, props.query.sort, props.query.dir);
}, []);
const updateStateWithBrews = (brews, page)=>{
setBrewCollection(brews || null);
setPageState(parseInt(page) || 1);
setSearching(false);
};
const updateUrl = (titleValue, authorValue, countValue, v3Value, legacyValue, page, sort, dir)=>{
const url = new URL(window.location.href);
const urlParams = new URLSearchParams(url.search);
urlParams.set('title', titleValue);
urlParams.set('author', authorValue);
urlParams.set('count', countValue);
urlParams.set('v3', v3Value);
urlParams.set('legacy', legacyValue);
urlParams.set('page', page);
urlParams.set('sort', sort);
urlParams.set('dir', dir);
url.search = urlParams.toString();
window.history.replaceState(null, '', url.toString());
};
const performSearch = async (title, author, count, v3, legacy, page, sort, dir)=>{
updateUrl(title, author, count, v3, legacy, page, sort, dir);
const response = await request
.get(`/api/vault?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}&count=${count}&page=${page}&sort=${sort}&dir=${dir}`)
.catch((error)=>{
console.log('error at loadPage: ', error);
setError(error);
updateStateWithBrews([], 1);
});
if(response.ok)
updateStateWithBrews(response.body.brews, page);
};
const loadTotal = async (title, author, v3, legacy)=>{
setTotalBrews(null);
const response = await request.get(`/api/vault/total?title=${title}&author=${author}&v3=${v3}&legacy=${legacy}`)
.catch((error)=>{
console.log('error at loadTotal: ', error);
setError(error);
updateStateWithBrews([], 1);
});
if(response.ok)
setTotalBrews(response.body.totalBrews);
};
const loadPage = async (page, updateTotal, sort, dir)=>{
if(!validateForm()) return;
setSearching(true);
setError(null);
const title = titleRef.current.value || '';
const author = authorRef.current.value || '';
const count = countRef.current.value || 10;
const v3 = v3Ref.current.checked != false;
const legacy = legacyRef.current.checked != false;
const sortOption = sort || 'title';
const dirOption = dir || 'asc';
const pageProp = page || 1;
setSort(sortOption);
setdir(dirOption);
performSearch(title, author, count, v3, legacy, pageProp, sortOption, dirOption);
if(updateTotal)
loadTotal(title, author, v3, legacy);
};
const renderNavItems = ()=>(
<Navbar>
<Nav.section>
<Nav.item className='brewTitle'>
Vault: Search for brews
</Nav.item>
</Nav.section>
<Nav.section>
<NewBrew />
<HelpNavItem />
<RecentNavItem />
<Account />
</Nav.section>
</Navbar>
);
const validateForm = ()=>{
//form validity: title or author must be written, and at least one renderer set
const isTitleValid = titleRef.current.validity.valid && titleRef.current.value;
const isAuthorValid = authorRef.current.validity.valid && authorRef.current.value;
const isCheckboxChecked = legacyRef.current.checked || v3Ref.current.checked;
const isFormValid = (isTitleValid || isAuthorValid) && isCheckboxChecked;
return isFormValid;
};
const disableSubmitIfFormInvalid = ()=>{
submitButtonRef.current.disabled = !validateForm();
};
const renderForm = ()=>(
<div className='brewLookup'>
<h2 className='formTitle'>Brew Lookup</h2>
<div className='formContents'>
<label>
Title of the brew
<input
ref={titleRef}
type='text'
name='title'
defaultValue={props.query.title || ''}
onKeyUp={disableSubmitIfFormInvalid}
pattern='.{3,}'
title='At least 3 characters'
onKeyDown={(e)=>{
if(e.key === 'Enter' && !submitButtonRef.current.disabled)
loadPage(1, true);
}}
placeholder='v3 Reference Document'
/>
</label>
<label>
Author of the brew
<input
ref={authorRef}
type='text'
name='author'
pattern='.{1,}'
defaultValue={props.query.author || ''}
onKeyUp={disableSubmitIfFormInvalid}
onKeyDown={(e)=>{
if(e.key === 'Enter' && !submitButtonRef.current.disabled)
loadPage(1, true);
}}
placeholder='Username'
/>
</label>
<label>
Results per page
<select ref={countRef} name='count' defaultValue={props.query.count || 20}>
<option value='10'>10</option>
<option value='20'>20</option>
<option value='40'>40</option>
<option value='60'>60</option>
</select>
</label>
<label>
<input
className='renderer'
ref={v3Ref}
type='checkbox'
defaultChecked={props.query.v3 !== 'false'}
onChange={disableSubmitIfFormInvalid}
/>
Search for v3 brews
</label>
<label>
<input
className='renderer'
ref={legacyRef}
type='checkbox'
defaultChecked={props.query.legacy !== 'false'}
onChange={disableSubmitIfFormInvalid}
/>
Search for legacy brews
</label>
<button
id='searchButton'
ref={submitButtonRef}
onClick={()=>{
loadPage(1, true);
}}
>
Search
<i
className={searching ? 'fas fa-spin fa-spinner': 'fas fa-search'}
/>
</button>
</div>
<legend>
<h3>Tips and tricks</h3>
<ul>
<li>
Only <b>published</b> brews are searchable via this tool
</li>
<li>
Usernames are case-sensitive
</li>
<li>
Use <code>"word"</code> to match an exact string,
and <code>-</code> to exclude words (at least one word must not be negated)
</li>
<li>
Some common words like "a", "after", "through", "itself", "here", etc.,
are ignored in searches. The full list can be found &nbsp;
<a href='https://github.com/mongodb/mongo/blob/0e3b3ca8480ddddf5d0105d11a94bd4698335312/src/mongo/db/fts/stop_words_english.txt'>
here
</a>
</li>
</ul>
<small>New features will be coming, such as filters and search by tags.</small>
</legend>
</div>
);
const renderSortOption = (optionTitle, optionValue)=>{
const oppositeDir = dirState === 'asc' ? 'desc' : 'asc';
return (
<div className={`sort-option ${sortState === optionValue ? `active` : ''}`}>
<button onClick={()=>loadPage(1, false, optionValue, oppositeDir)}>
{optionTitle}
</button>
{sortState === optionValue && (
<i className={`sortDir fas ${dirState === 'asc' ? 'fa-sort-up' : 'fa-sort-down'}`} />
)}
</div>
);
};
const renderSortBar = ()=>{
return (
<div className='sort-container'>
{renderSortOption('Title', 'title', props.query.dir)}
{renderSortOption('Created Date', 'createdAt', props.query.dir)}
{renderSortOption('Updated Date', 'updatedAt', props.query.dir)}
{renderSortOption('Views', 'views', props.query.dir)}
</div>
);
};
const renderPaginationControls = ()=>{
if(!totalBrews) return null;
const countInt = parseInt(props.query.count || 20);
const totalPages = Math.ceil(totalBrews / countInt);
let startPage, endPage;
if(pageState <= 6) {
startPage = 1;
endPage = Math.min(totalPages, 10);
} else if(pageState + 4 >= totalPages) {
startPage = Math.max(1, totalPages - 9);
endPage = totalPages;
} else {
startPage = pageState - 5;
endPage = pageState + 4;
}
const pagesAroundCurrent = new Array(endPage - startPage + 1)
.fill()
.map((_, index)=>(
<a
key={startPage + index}
className={`pageNumber ${pageState === startPage + index ? 'currentPage' : ''}`}
onClick={()=>loadPage(startPage + index, false, sortState, dirState)}
>
{startPage + index}
</a>
));
return (
<div className='paginationControls'>
<button
className='previousPage'
onClick={()=>loadPage(pageState - 1, false, sortState, dirState)}
disabled={pageState === startPage}
>
<i className='fa-solid fa-chevron-left'></i>
</button>
<ol className='pages'>
{startPage > 1 && (
<a
className='pageNumber firstPage'
onClick={()=>loadPage(1, false, sortState, dirState)}
>
1 ...
</a>
)}
{pagesAroundCurrent}
{endPage < totalPages && (
<a
className='pageNumber lastPage'
onClick={()=>loadPage(totalPages, false, sortState, dirState)}
>
... {totalPages}
</a>
)}
</ol>
<button
className='nextPage'
onClick={()=>loadPage(pageState + 1, false, sortState, dirState)}
disabled={pageState === totalPages}
>
<i className='fa-solid fa-chevron-right'></i>
</button>
</div>
);
};
const renderFoundBrews = ()=>{
if(searching) {
return (
<div className='foundBrews searching'>
<h3 className='searchAnim'>Searching</h3>
</div>
);
}
if(error) {
const errorText = ErrorIndex()[error.HBErrorCode.toString()] || '';
return (
<div className='foundBrews noBrews'>
<h3>Error: {errorText}</h3>
</div>
);
}
if(!brewCollection) {
return (
<div className='foundBrews noBrews'>
<h3>No search yet</h3>
</div>
);
}
if(brewCollection.length === 0) {
return (
<div className='foundBrews noBrews'>
<h3>No brews found</h3>
</div>
);
}
return (
<div className='foundBrews'>
<span className='totalBrews'>
{`Brews found: `}
<span>{totalBrews}</span>
</span>
{brewCollection.map((brew, index)=>{
return (
<BrewItem
brew={{ ...brew }}
key={index}
reportError={props.reportError}
renderStorage={false}
/>
);
})}
{renderPaginationControls()}
</div>
);
};
return (
<div className='sitePage vaultPage'>
<link href='/themes/V3/Blank/style.css' rel='stylesheet' />
<link href='/themes/V3/5ePHB/style.css' rel='stylesheet' />
{renderNavItems()}
<div className="content">
<SplitPane showDividerButtons={false}>
<div className='form dataGroup'>{renderForm()}</div>
<div className='resultsContainer dataGroup'>
{renderSortBar()}
{renderFoundBrews()}
</div>
</SplitPane>
</div>
</div>
);
};
module.exports = VaultPage;

View File

@@ -0,0 +1,358 @@
.vaultPage {
height : 100%;
overflow-y : hidden;
background-color : #2C3E50;
*:not(input) { user-select : none; }
.content .dataGroup {
width : 100%;
height : 100%;
background : white;
&.form .brewLookup {
position : relative;
padding : 50px clamp(20px, 4vw, 50px);
small {
font-size : 10pt;
color : #555555;
a { color : #333333; }
}
code {
padding-inline : 5px;
font-family : monospace;
background : lightgrey;
border-radius : 5px;
}
h1, h2, h3, h4 {
font-family : 'CodeBold';
letter-spacing : 2px;
}
legend {
h3 {
margin-block : 30px 20px;
font-size : 20px;
text-align : center;
border-bottom : 2px solid;
}
ul {
padding-inline : 30px 10px;
li {
margin-block : 5px;
line-height : calc(1em + 5px);
list-style : disc;
}
}
}
&::after {
position : absolute;
top : 0;
right : 0;
left : 0;
display : block;
padding : 10px;
font-weight : 900;
color : white;
white-space : pre-wrap;
content : 'Error:\A At least one renderer should be enabled to make a search';
background : rgb(255, 60, 60);
opacity : 0;
transition : opacity 0.5s;
}
&:not(:has(input[type='checkbox']:checked))::after { opacity : 1; }
.formTitle {
margin : 20px 0;
font-size : 30px;
color : black;
text-align : center;
border-bottom : 2px solid;
}
.formContents {
position : relative;
display : flex;
flex-direction : column;
label {
display : flex;
align-items : center;
margin : 10px 0;
}
select { margin : 0 10px; }
input {
margin : 0 10px;
&:invalid { background : rgb(255, 188, 181); }
}
#searchButton {
.colorButton(@green);
position : absolute;
right : 20px;
bottom : 0;
i {
margin-left : 10px;
animation-duration : 1000s;
}
}
}
}
&.resultsContainer {
display : flex;
flex-direction : column;
height : 100%;
overflow-y : auto;
font-size : 0.34cm;
h3 {
font-family : 'Open Sans';
font-weight : 900;
color : white;
}
.sort-container {
display : flex;
flex-wrap : wrap;
column-gap : 15px;
justify-content : center;
height : 30px;
color : white;
background-color : #555555;
border-top : 1px solid #666666;
border-bottom : 1px solid #666666;
.sort-option {
display : flex;
align-items : center;
padding : 0 8px;
&:hover { background-color : #444444; }
&.active {
background-color : #333333;
button {
font-weight : 800;
color : white;
& + .sortDir { padding-left : 5px; }
}
}
button {
padding : 0;
font-size : 11px;
font-weight : normal;
color : #CCCCCC;
text-transform : uppercase;
background-color : transparent;
&:hover { background : none; }
}
}
}
.foundBrews {
position : relative;
width : 100%;
height : 100%;
max-height : 100%;
padding : 50px 50px 70px 50px;
overflow-y : scroll;
background-color : #2C3E50;
h3 { font-size : 25px; }
&.noBrews {
display : grid;
place-items : center;
color : white;
}
&.searching {
display : grid;
place-items : center;
color : white;
h3 { position : relative; }
h3.searchAnim::after {
position : absolute;
top : 50%;
right : 0;
width : max-content;
height : 1em;
content : '';
translate : calc(100% + 5px) -50%;
animation : trailingDots 2s ease infinite;
}
}
.totalBrews {
position : fixed;
right : 0;
bottom : 0;
z-index : 1000;
padding : 8px 10px;
font-family : 'Open Sans';
font-size : 11px;
font-weight : 800;
color : white;
background-color : #333333;
.searchAnim {
position : relative;
display : inline-block;
width : 3ch;
height : 1em;
}
.searchAnim::after {
position : absolute;
top : 50%;
right : 0;
width : max-content;
height : 1em;
content : '';
translate : -50% -50%;
animation : trailingDots 2s ease infinite;
}
}
.brewItem {
width : 47%;
margin-right : 40px;
color : black;
isolation : isolate;
&::after {
position : absolute;
inset : 0;
z-index : -2;
display : block;
content : '';
background-image : url('/assets/parchmentBackground.jpg');
}
&:nth-child(even of .brewItem) { margin-right : 0; }
h2 {
font-family : 'MrEavesRemake';
font-size : 0.75cm;
font-weight : 800;
line-height : 0.988em;
color : var(--HB_Color_HeaderText);
}
.info {
position : relative;
z-index : 2;
font-family : 'ScalySansRemake';
font-size : 1.2em;
>span {
margin-right : 12px;
line-height : 1.5em;
}
}
.links { z-index : 2; }
hr {
margin : 0px;
visibility : hidden;
}
.thumbnail { z-index : -1; }
}
.paginationControls {
position : absolute;
left : 50%;
display : grid;
grid-template-areas : 'previousPage currentPage nextPage';
grid-template-columns : 50px 1fr 50px;
place-items : center;
width : auto;
translate : -50%;
.pages {
display : flex;
grid-area : currentPage;
justify-content : space-evenly;
width : 100%;
height : 100%;
padding : 5px 8px;
text-align : center;
.pageNumber {
margin-inline : 1vw;
font-family : 'Open Sans';
font-weight : 900;
color : white;
text-underline-position : under;
text-wrap : nowrap;
cursor : pointer;
&.currentPage {
color : gold;
text-decoration : underline;
pointer-events : none;
}
&.firstPage { margin-right : -5px; }
&.lastPage { margin-left : -5px; }
}
}
button {
.colorButton(@green);
width : max-content;
&.previousPage { grid-area : previousPage; }
&.nextPage { grid-area : nextPage; }
}
}
}
}
}
}
@keyframes trailingDots {
0%,
32% { content : ' .'; }
33%,
65% { content : ' ..'; }
66%,
100% { content : ' ...'; }
}
// media query for when the page is smaller than 1079 px in width
@media screen and (max-width : 1079px) {
.vaultPage {
.dataGroup.form .brewLookup { padding : 1px 20px 20px 10px; }
.dataGroup.resultsContainer .foundBrews .brewItem {
width : 100%;
margin-inline : auto;
}
}
}

View File

@@ -0,0 +1,19 @@
import * as IDB from 'idb-keyval/dist/index.js';
export function initCustomStore(db, store){
const createCustomStore = async ()=>IDB.createStore(db, store);
return {
entries : async ()=>IDB.entries(await createCustomStore()),
keys : async ()=>IDB.keys(await createCustomStore()),
values : async ()=>IDB.values(await createCustomStore()),
clear : async ()=>IDB.clear(await createCustomStore),
get : async (key)=>IDB.get(key, await createCustomStore()),
getMany : async (keys)=>IDB.getMany(keys, await createCustomStore()),
set : async (key, value)=>IDB.set(key, value, await createCustomStore()),
setMany : async (entries)=>IDB.setMany(entries, await createCustomStore()),
update : async (key, updateFn)=>IDB.update(key, updateFn, await createCustomStore()),
del : async (key)=>IDB.del(key, await createCustomStore()),
delMany : async (keys)=>IDB.delMany(keys, await createCustomStore())
};
};

View File

@@ -1,4 +1,4 @@
const request = require('superagent');
import request from 'superagent';
const addHeader = (request)=>request.set('Homebrewery-Version', global.version);
@@ -9,4 +9,4 @@ const requestMiddleware = {
delete : (path)=>addHeader(request.delete(path)),
};
module.exports = requestMiddleware;
export default requestMiddleware;

View File

@@ -0,0 +1,119 @@
import { initCustomStore } from './customIDBStore.js';
export const HISTORY_PREFIX = 'HOMEBREWERY-HISTORY';
export const HISTORY_SLOTS = 5;
// History values in minutes
const HISTORY_SAVE_DELAYS = {
'0' : 0,
'1' : 2,
'2' : 10,
'3' : 60,
'4' : 12 * 60,
'5' : 2 * 24 * 60
};
// const HISTORY_SAVE_DELAYS = {
// '0' : 0,
// '1' : 1,
// '2' : 2,
// '3' : 3,
// '4' : 4,
// '5' : 5
// };
const GARBAGE_COLLECT_DELAY = 28 * 24 * 60;
// const GARBAGE_COLLECT_DELAY = 10;
const HB_DB = 'HOMEBREWERY-DB';
const HB_STORE = 'HISTORY';
const IDB = initCustomStore(HB_DB, HB_STORE);
function getKeyBySlot(brew, slot){
// Return a string representing the key for this brew and history slot
return `${HISTORY_PREFIX}-${brew.shareId}-${slot}`;
};
function parseBrewForStorage(brew, slot = 0) {
// Strip out unneeded object properties
// Returns an array of [ key, brew ]
const archiveBrew = {
title : brew.title,
text : brew.text,
style : brew.style,
version : brew.version,
shareId : brew.shareId,
savedAt : brew?.savedAt || new Date(),
expireAt : new Date()
};
archiveBrew.expireAt.setMinutes(archiveBrew.expireAt.getMinutes() + HISTORY_SAVE_DELAYS[slot]);
const key = getKeyBySlot(brew, slot);
return [key, archiveBrew];
}
export async function loadHistory(brew){
const DEFAULT_HISTORY_ITEM = { expireAt: '2000-01-01T00:00:00.000Z', shareId: brew.shareId, noData: true };
const historyKeys = [];
// Create array of all history keys
for (let i = 1; i <= HISTORY_SLOTS; i++){
historyKeys.push(getKeyBySlot(brew, i));
};
// Load all keys from IDB at once
const dataArray = await IDB.getMany(historyKeys);
return dataArray.map((data)=>{ return data ?? DEFAULT_HISTORY_ITEM; });
}
export async function updateHistory(brew) {
const history = await loadHistory(brew);
// Walk each version position
for (let slot = HISTORY_SLOTS - 1; slot >= 0; slot--){
const storedVersion = history[slot];
// If slot has expired, update all lower slots and break
if(new Date() >= new Date(storedVersion.expireAt)){
// Create array of arrays : [ [key1, value1], [key2, value2], ..., [keyN, valueN] ]
// to pass to IDB.setMany
const historyUpdate = [];
for (let updateSlot = slot; updateSlot > 0; updateSlot--){
// Move data from updateSlot to updateSlot + 1
if(!history[updateSlot - 1]?.noData) {
historyUpdate.push(parseBrewForStorage(history[updateSlot - 1], updateSlot + 1));
}
};
// Update the most recent brew
historyUpdate.push(parseBrewForStorage(brew, 1));
await IDB.setMany(historyUpdate);
// Break out of data checks because we found an expired value
break;
}
};
};
export async function versionHistoryGarbageCollection(){
const entries = await IDB.entries();
const expiredKeys = [];
for (const [key, value] of entries){
const expireAt = new Date(value.savedAt);
expireAt.setMinutes(expireAt.getMinutes() + GARBAGE_COLLECT_DELAY);
if(new Date() > expireAt){
expiredKeys.push(key);
};
};
if(expiredKeys.length > 0){
await IDB.delMany(expiredKeys);
}
};

View File

@@ -1,57 +1,84 @@
.fac {
display : inline-block;
display : inline-block;
background-color : currentColor;
mask-size : contain;
mask-repeat : no-repeat;
mask-position : center;
width : 1em;
aspect-ratio : 1;
}
.position-top-left {
content: url('../icons/position-top-left.svg');
mask-image: url('../icons/position-top-left.svg');
}
.position-top-right {
content: url('../icons/position-top-right.svg');
mask-image: url('../icons/position-top-right.svg');
}
.position-bottom-left {
content: url('../icons/position-bottom-left.svg');
mask-image: url('../icons/position-bottom-left.svg');
}
.position-bottom-right {
content: url('../icons/position-bottom-right.svg');
mask-image: url('../icons/position-bottom-right.svg');
}
.position-top {
content: url('../icons/position-top.svg');
mask-image: url('../icons/position-top.svg');
}
.position-right {
content: url('../icons/position-right.svg');
mask-image: url('../icons/position-right.svg');
}
.position-bottom {
content: url('../icons/position-bottom.svg');
mask-image: url('../icons/position-bottom.svg');
}
.position-left {
content: url('../icons/position-left.svg');
mask-image: url('../icons/position-left.svg');
}
.mask-edge {
content: url('../icons/mask-edge.svg');
mask-image: url('../icons/mask-edge.svg');
}
.mask-corner {
content: url('../icons/mask-corner.svg');
mask-image: url('../icons/mask-corner.svg');
}
.mask-center {
content: url('../icons/mask-center.svg');
mask-image: url('../icons/mask-center.svg');
}
.book-front-cover {
content: url('../icons/book-front-cover.svg');
mask-image: url('../icons/book-front-cover.svg');
}
.book-back-cover {
content: url('../icons/book-back-cover.svg');
mask-image: url('../icons/book-back-cover.svg');
}
.book-inside-cover {
content: url('../icons/book-inside-cover.svg');
mask-image: url('../icons/book-inside-cover.svg');
}
.book-part-cover {
content: url('../icons/book-part-cover.svg');
mask-image: url('../icons/book-part-cover.svg');
}
.image-wrap-left {
mask-image: url('../icons/image-wrap-left.svg');
}
.image-wrap-right {
mask-image: url('../icons/image-wrap-right.svg');
}
.davek {
content: url('../icons/Davek.svg');
mask-image: url('../icons/Davek.svg');
}
.rellanic {
content: url('../icons/Rellanic.svg');
mask-image: url('../icons/Rellanic.svg');
}
.iokharic {
content: url('../icons/Iokharic.svg');
mask-image: url('../icons/Iokharic.svg');
}
.zoom-to-fit {
mask-image: url('../icons/zoom-to-fit.svg');
}
.fit-width {
mask-image: url('../icons/fit-width.svg');
}
.single-spread {
mask-image: url('../icons/single-spread.svg');
}
.facing-spread {
mask-image: url('../icons/facing-spread.svg');
}
.flow-spread {
mask-image: url('../icons/flow-spread.svg');
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.979101,0,0,0.919064,-29.0748,1.98095)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
<g transform="matrix(0.979101,0,0,0.919064,23.058,1.98095)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1.07509,0,0,1.07509,-3.75511,-3.75468)">
<g transform="matrix(0.843549,0,0,0.950644,8.38004,4.39672)">
<path d="M28.455,52.413L28.455,58.581C28.455,59.719 27.684,60.745 26.501,61.181C25.318,61.616 23.956,61.375 23.051,60.571L11.114,49.96C9.878,48.862 9.878,47.08 11.114,45.981L23.051,35.371C23.956,34.566 25.318,34.326 26.501,34.761C27.684,35.197 28.455,36.223 28.455,37.361L28.455,43.528L70.223,43.528L70.223,37.361C70.223,36.223 70.995,35.197 72.177,34.761C73.36,34.326 74.722,34.566 75.627,35.371L87.564,45.981C88.8,47.08 88.8,48.862 87.564,49.96L75.627,60.571C74.722,61.375 73.36,61.616 72.177,61.181C70.995,60.745 70.223,59.719 70.223,58.581L70.223,52.413L28.455,52.413Z"/>
</g>
<g transform="matrix(1.46702,0,0,0.986488,-23.0335,3.50686)">
<path d="M23.967,5.877L23.967,88.383C23.967,90.556 22.781,92.321 21.319,92.321L21.157,92.321C19.695,92.321 18.509,90.556 18.509,88.383L18.509,5.877C18.509,3.703 19.695,1.939 21.157,1.939L21.319,1.939C22.781,1.939 23.967,3.703 23.967,5.877Z"/>
</g>
<g transform="matrix(1.46702,0,0,0.986488,60.7211,3.50686)">
<path d="M23.967,5.877L23.967,88.383C23.967,90.556 22.781,92.321 21.319,92.321L21.157,92.321C19.695,92.321 18.509,90.556 18.509,88.383L18.509,5.877C18.509,3.703 19.695,1.939 21.157,1.939L21.319,1.939C22.781,1.939 23.967,3.703 23.967,5.877Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1.0781,0,0,1.0781,-3.90545,-3.90502)">
<g transform="matrix(0.590052,0,0,0.553871,-13.8993,-2.19227)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
<g transform="matrix(0.590052,0,0,0.553871,-13.8993,44.3152)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
<g transform="matrix(0.590052,0,0,0.553871,17.5184,-2.19227)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
<g transform="matrix(0.590052,0,0,0.553871,50.0095,-2.19227)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
<g transform="matrix(0.590052,0,0,0.553871,17.5184,44.3152)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
<g transform="matrix(0.590052,0,0,0.553871,50.0095,44.3152)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
x="0px"
y="0px"
viewBox="0 0 512.00006 512"
xml:space="preserve"
id="svg10"
sodipodi:docname="noun-wrap-image-left-212078.svg"
width="512.00006"
height="512"
inkscape:export-filename="image-wrap-right.svg"
inkscape:export-xdpi="300"
inkscape:export-ydpi="300"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs10" /><sodipodi:namedview
id="namedview10"
pagecolor="#ffffff"
bordercolor="#111111"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 185.80018,144 H 32"
id="path11"
sodipodi:nodetypes="cc"
clip-path="none"
inkscape:export-filename="image-wrap-right.svg"
inkscape:export-xdpi="300"
inkscape:export-ydpi="300" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 185.80018,368 H 32"
id="path11-8"
sodipodi:nodetypes="cc"
clip-path="none" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 480.00007,32 H 32"
id="path11-8-2-67"
clip-path="none"
sodipodi:nodetypes="cc" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 480.00008,480 H 32"
id="path11-8-2-67-2"
clip-path="none"
sodipodi:nodetypes="cc" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 160.0001,255.98832 32,256.01162"
id="path11-0"
sodipodi:nodetypes="cc"
clip-path="none" /><path
id="path23"
style="opacity:0.922046;fill:#000000;fill-opacity:1;stroke-width:64;stroke-linecap:round;stroke-dasharray:none;paint-order:fill markers stroke"
d="m 416.00008,96 a 160,160 0 0 1 96,32.50977 v 254.98046 a 160,160 0 0 1 -96,32.50977 160,160 0 0 1 -160,-160 160,160 0 0 1 160,-160 z" /></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
x="0px"
y="0px"
viewBox="0 0 512.00006 512"
xml:space="preserve"
id="svg10"
sodipodi:docname="noun-wrap-image-left-212078.svg"
width="512.00006"
height="512"
inkscape:export-filename="image-wrap-right.svg"
inkscape:export-xdpi="300"
inkscape:export-ydpi="300"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs10" /><sodipodi:namedview
id="namedview10"
pagecolor="#ffffff"
bordercolor="#111111"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 326.1999,144 H 480.00008"
id="path11"
sodipodi:nodetypes="cc"
clip-path="none"
inkscape:export-filename="image-wrap-right.svg"
inkscape:export-xdpi="300"
inkscape:export-ydpi="300" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 326.1999,368 H 480.00008"
id="path11-8"
sodipodi:nodetypes="cc"
clip-path="none" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 32.00001,32 H 480.00008"
id="path11-8-2-67"
clip-path="none"
sodipodi:nodetypes="cc" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 32,480 H 480.00008"
id="path11-8-2-67-2"
clip-path="none"
sodipodi:nodetypes="cc" /><path
style="fill:none;stroke:#000000;stroke-width:64;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 351.99998,255.98832 128.0001,0.0233"
id="path11-0"
sodipodi:nodetypes="cc"
clip-path="none" /><path
id="path23"
style="opacity:0.922046;fill:#000000;fill-opacity:1;stroke-width:64;stroke-linecap:round;stroke-dasharray:none;paint-order:fill markers stroke"
d="M 96,96 A 160,160 0 0 0 0,128.50977 V 383.49023 A 160,160 0 0 0 96,416 160,160 0 0 0 256,256 160,160 0 0 0 96,96 Z" /></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1.41826,0,0,1.3313,-26.7845,-19.5573)">
<path d="M78.584,16.13C78.584,15.335 78.164,14.69 77.647,14.69L30.632,14.69C30.115,14.69 29.695,15.335 29.695,16.13L29.695,88.365C29.695,89.16 30.115,89.805 30.632,89.805L77.647,89.805C78.164,89.805 78.584,89.16 78.584,88.365L78.584,16.13Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 777 B

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1.0781,0,0,1.0781,-3.90545,-3.90502)">
<g transform="matrix(0.841196,0,0,0.947993,8.49652,4.52391)">
<path d="M44.333,52.413L28.455,52.413L28.455,58.581C28.455,59.719 27.684,60.745 26.501,61.181C25.318,61.616 23.956,61.375 23.051,60.571L11.114,49.96C9.878,48.862 9.878,47.08 11.114,45.981L23.051,35.371C23.956,34.566 25.318,34.326 26.501,34.761C27.684,35.197 28.455,36.223 28.455,37.361L28.455,43.528L44.333,43.528L44.333,29.439L37.382,29.439C36.099,29.439 34.943,28.755 34.452,27.705C33.961,26.656 34.233,25.448 35.14,24.644L47.097,14.052C48.335,12.956 50.343,12.956 51.581,14.052L63.539,24.644C64.446,25.448 64.717,26.656 64.226,27.705C63.735,28.755 62.579,29.439 61.296,29.439L54.346,29.439L54.346,43.528L70.223,43.528L70.223,37.361C70.223,36.223 70.995,35.197 72.177,34.761C73.36,34.326 74.722,34.566 75.627,35.371L87.564,45.981C88.8,47.08 88.8,48.862 87.564,49.96L75.627,60.571C74.722,61.375 73.36,61.616 72.177,61.181C70.995,60.745 70.223,59.719 70.223,58.581L70.223,52.413L54.346,52.413L54.346,66.502L61.296,66.502C62.579,66.502 63.735,67.187 64.226,68.236C64.717,69.286 64.446,70.494 63.539,71.297L51.581,81.889C50.343,82.986 48.335,82.986 47.097,81.889L35.14,71.297C34.233,70.494 33.961,69.286 34.452,68.236C34.943,67.187 36.099,66.502 37.382,66.502L44.333,66.503L44.333,52.413Z"/>
</g>
<g transform="matrix(1.0247,0,0,1.0247,-5.47698,-3.53855)">
<path d="M99.4,14.269L99.4,90.227C99.4,94.245 96.137,97.508 92.119,97.508L16.161,97.508C12.142,97.508 8.88,94.245 8.88,90.227L8.88,14.269C8.88,10.25 12.142,6.988 16.161,6.988L92.119,6.988C96.137,6.988 99.4,10.25 99.4,14.269ZM93.633,14.269C93.633,13.433 92.955,12.755 92.119,12.755L16.161,12.755C15.325,12.755 14.647,13.433 14.647,14.269L14.647,90.227C14.647,91.062 15.325,91.741 16.161,91.741L92.119,91.741C92.955,91.741 93.633,91.062 93.633,90.227L93.633,14.269Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -8,6 +8,8 @@ const template = async function(name, title='', props = {}){
});
const ogMetaTags = ogTags.join('\n');
const ssrModule = await import(`../build/${name}/ssr.cjs`);
return `<!DOCTYPE html>
<html>
<head>
@@ -21,7 +23,7 @@ const template = async function(name, title='', props = {}){
<title>${title.length ? `${title} - The Homebrewery`: 'The Homebrewery - NaturalCrit'}</title>
</head>
<body>
<main id="reactRoot">${require(`../build/${name}/ssr.js`)(props)}</main>
<main id="reactRoot">${ssrModule.default(props)}</main>
<script src=${`/${name}/bundle.js`}></script>
<script>start_app(${JSON.stringify(props)})</script>
</body>
@@ -29,4 +31,4 @@ const template = async function(name, title='', props = {}){
`;
};
module.exports = template;
export default template;

View File

@@ -4,6 +4,9 @@
"secret" : "secret",
"web_port" : 8000,
"enable_v3" : true,
"enable_themes" : true,
"local_environments" : ["docker", "local"],
"publicUrl" : "https://homebrewery.naturalcrit.com"
"publicUrl" : "https://homebrewery.naturalcrit.com",
"hb_images" : null,
"hb_fonts" : null
}

71
eslint.config.mjs Normal file
View File

@@ -0,0 +1,71 @@
import react from "eslint-plugin-react";
import jest from "eslint-plugin-jest";
import globals from "globals";
export default [{
ignores: ["build/"]
},
{
files : ['**/*.js', '**/*.jsx'],
plugins : { react, jest },
languageOptions : {
ecmaVersion : "latest",
sourceType : "module",
parserOptions : { ecmaFeatures: { jsx: true } },
globals : { ...globals.browser, ...globals.node }
},
rules: {
/** Errors **/
"camelcase" : ["error", { properties: "never" }],
"no-array-constructor" : "error",
"no-iterator" : "error",
"no-nested-ternary" : "error",
"no-new-object" : "error",
"no-proto" : "error",
"react/jsx-no-bind" : ["error", { allowArrowFunctions: true }],
"react/jsx-uses-react" : "error",
"react/prefer-es6-class" : ["error", "never"],
"jest/valid-expect" : ["error", { maxArgs: 3 }],
/** Warnings **/
"max-lines" : ["warn", { max: 200, skipComments: true, skipBlankLines: true }],
"max-depth" : ["warn", { max: 4 }],
"max-params" : ["warn", { max: 5 }],
"no-restricted-syntax" : ["warn", "ClassDeclaration", "SwitchStatement"],
"no-unused-vars" : ["warn", { vars: "all", args: "none", varsIgnorePattern: "config|_|cx|createClass" }],
"react/jsx-uses-vars" : "warn",
/** Fixable **/
"arrow-parens" : ["warn", "always"],
"brace-style" : ["warn", "1tbs", { allowSingleLine: true }],
"jsx-quotes" : ["warn", "prefer-single"],
"no-var" : "warn",
"prefer-const" : "warn",
"prefer-template" : "warn",
"quotes" : ["warn", "single", { allowTemplateLiterals: true }],
"semi" : ["warn", "always"],
/** Whitespace **/
"array-bracket-spacing" : ["warn", "never"],
"arrow-spacing" : ["warn", { before: false, after: false }],
"comma-spacing" : ["warn", { before: false, after: true }],
"indent" : ["warn", "tab", { MemberExpression: "off" }],
"linebreak-style" : "off",
"no-trailing-spaces" : "warn",
"no-whitespace-before-property" : "warn",
"object-curly-spacing" : ["warn", "always"],
"react/jsx-indent-props" : ["warn", "tab"],
"space-in-parens" : ["warn", "never"],
"template-curly-spacing" : ["warn", "never"],
"keyword-spacing" : ["warn", {
before : true,
after : true,
overrides : { if: { before: false, after: false } }
}],
"key-spacing" : ["warn", {
multiLine : { beforeColon: true, afterColon: true, align: "colon" },
singleLine : { beforeColon: false, afterColon: true }
}]
}
}
];

19
faq.md
View File

@@ -69,7 +69,6 @@ pre {
You can check the site status here: [Everyone or Just Me](https://downforeveryoneorjustme.com/homebrewery.naturalcrit.com)
### Why am I getting an error when trying to save, and my account is linked to Google?
A sign-in with Google only lasts a year until the authentication expires. You must go [here](https://www.naturalcrit.com/login), click the *Log-out* button, and then sign back in using your Google account.
@@ -82,12 +81,17 @@ If you have linked your account with a Google account, you would change your pas
### Is there a way to restore a previous version of my brew?
Currently, there is no way to do this through the site yourself. This would take too much of a toll on the amount of storage the homebrewery requires. However, we do have daily backups of our database that we keep for 8 days, and you can contact the moderators on [the subreddit](https://www.reddit.com/r/homebrewery) with your Homebrewery username, the name of the lost brew, and the last known time it was working properly. We can manually look through our backups and restore it if it exists.
In your brew, there is an icon, :fas_clock_rotate_left:, that button opens up a menu with versions of your brew, stored in order from newer to older, up to a week old. Because of the amount of duplicates this function creates, this information is stored in **your browser**, so if you were to uninstall it or clear your cookies and site data, or change computers, the info will not be there.
Also, we do have daily backups of our database that we keep for 8 days, and you can contact the moderators on [the subreddit](https://www.reddit.com/r/homebrewery) with your Homebrewery username, the name of the lost brew, and the last known time it was working properly. We can manually look through our backups and restore it if it exists.
### I worked on a brew for X hours, and suddenly all the text disappeared!
This usually happens if you accidentally drag-select all of your text and then start typing which overwrites the selection. Do not panic, and do not refresh the page or reload your brew quite yet as it is probably auto-saved in this state already. Simply press CTRL+Z as many times as needed to undo your last few changes and you will be back to where you were, then make sure to save your brew in the "good" state.
You can also load a history version old enough to have all the text, using the :fas_clock_rotate_left: history versions button.
\column
### Why is only Chrome supported?
@@ -112,10 +116,7 @@ Once you have an image you would like to use, it is recommended to host it somew
\page
### A particular font does not work for my language, what do I do?
The fonts used were originally created for use with the English language, though revisions since then have added more support for other languages. They are still not complete sets and may be missing a glyph/character you need. Unfortunately, the volunteer group as it stands at the time of this writing does not have a font guru, so it would be difficult to add more glyphs (especially complicated glyphs). Let us know which glyph is missing on the subreddit, but you may need to search [Google Fonts](https://fonts.google.com) for an alternative font if you need something fast.
### Whenever I click on the "Get PDF" button, instead of getting a download, it opens Print Preview in another tab.
Yes, this is by design. In the print preview, select "Save as PDF" as the Destination, and then click "Save". There will be a normal download dialog where you can save your brew as a PDF.
The fonts used were originally created for use with the English language, though revisions since then have added more support for other languages. They are still not complete sets and may be missing a glyph/character you need. Unfortunately, the volunteer group as it stands at the time of this writing does not have a font guru, so it would be difficult to add more glyphs (especially complicated glyphs). Let us know which glyph is missing on the subreddit, but you may need to search [Google Fonts](https://fonts.google.com) for an alternative font if you need something fast.
### I have white borders on the bottom/sides of the print preview.
@@ -126,4 +127,8 @@ The Homebrewery defaults to creating US Letter page sizes. If you are printing
### Typing `#### Adhesion` in the text editor doesn't show the header at all in the completed page?
Your ad-blocking software is mistakenly assuming your text to be an ad. Whitelist homebrewery.naturalcrit.com in your ad-blocking software.
Your ad-blocking software is mistakenly assuming your text to be an ad. We recommend whitelisting homebrewery.naturalcrit.com in your ad-blocking software, as we have no ads.
### My username appears as _hidden_ when checking my brews in the Vault, why is that?
Your username is most likely your e-mail adress, and our code is picking that up and protecting your identity. This will remain as is, but you can ask for a name change by contacting the moderators on [the subreddit](https://www.reddit.com/r/homebrewery) with your Homebrewery username, and your desired new name. You will also be asked to provide details about some of your unpublished brews, to verify your identity. No information will be leaked or shared.

6745
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,32 @@
{
"name": "homebrewery",
"description": "Create authentic looking D&D homebrews using only markdown",
"version": "3.13.1",
"version": "3.16.1",
"type": "module",
"engines": {
"npm": "^10.2.x",
"node": "^20.8.x"
"node": "^20.18.x"
},
"repository": {
"type": "git",
"url": "git://github.com/naturalcrit/homebrewery.git"
},
"scripts": {
"dev": "node scripts/dev.js",
"quick": "node scripts/quick.js",
"build": "node scripts/buildHomebrew.js && node scripts/buildAdmin.js",
"builddev": "node scripts/buildHomebrew.js --dev",
"lint": "eslint --fix **/*.{js,jsx}",
"lint:dry": "eslint **/*.{js,jsx}",
"dev": "node --experimental-require-module scripts/dev.js",
"quick": "node --experimental-require-module scripts/quick.js",
"build": "node --experimental-require-module scripts/buildHomebrew.js && node --experimental-require-module scripts/buildAdmin.js",
"builddev": "node --experimental-require-module scripts/buildHomebrew.js --dev",
"lint": "eslint --fix",
"lint:dry": "eslint",
"stylelint": "stylelint --fix **/*.{less}",
"stylelint:dry": "stylelint **/*.less",
"circleci": "npm test && eslint **/*.{js,jsx} --max-warnings=0",
"verify": "npm run lint && npm test",
"test": "jest --runInBand",
"test:api-unit": "jest server/*.spec.js --verbose",
"test:api-unit": "jest \"server/.*.spec.js\" --verbose",
"test:api-unit:themes": "jest \"server/.*.spec.js\" -t \"theme bundle\" --verbose",
"test:api-unit:css": "jest \"server/.*.spec.js\" -t \"Get CSS\" --verbose",
"test:api-unit:notifications": "jest \"server/.*.spec.js\" -t \"Notifications\" --verbose",
"test:coverage": "jest --coverage --silent --runInBand",
"test:dev": "jest --verbose --watch",
"test:basic": "jest tests/markdown/basic.test.js --verbose",
@@ -32,12 +36,14 @@
"test:mustache-syntax:block": "jest \".*(mustache-syntax).*\" -t '^Block:.*' --verbose --noStackTrace",
"test:mustache-syntax:injection": "jest \".*(mustache-syntax).*\" -t '^Injection:.*' --verbose --noStackTrace",
"test:definition-lists": "jest tests/markdown/definition-lists.test.js --verbose --noStackTrace",
"test:hard-breaks": "jest tests/markdown/hard-breaks.test.js --verbose --noStackTrace",
"test:emojis": "jest tests/markdown/emojis.test.js --verbose --noStackTrace",
"test:route": "jest tests/routes/static-pages.test.js --verbose",
"phb": "node scripts/phb.js",
"test:safehtml": "jest tests/html/safeHTML.test.js --verbose",
"phb": "node --experimental-require-module scripts/phb.js",
"prod": "set NODE_ENV=production && npm run build",
"postinstall": "npm run build",
"start": "node server.js"
"start": "node --experimental-require-module server.js"
},
"author": "stolksdorf",
"license": "MIT",
@@ -51,20 +57,23 @@
"shared",
"server"
],
"transformIgnorePatterns": [
"node_modules/(?!nanoid/).*"
],
"coveragePathIgnorePatterns": [
"build/*"
],
"coverageThreshold": {
"global": {
"statements": 25,
"branches": 10,
"functions": 22,
"lines": 25
"statements": 50,
"branches": 40,
"functions": 40,
"lines": 50
},
"server/homebrew.api.js": {
"statements": 65,
"statements": 70,
"branches": 50,
"functions": 60,
"functions": 65,
"lines": 70
}
},
@@ -72,66 +81,61 @@
"jest-expect-message"
]
},
"babel": {
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-transform-runtime"
]
},
"dependencies": {
"@babel/core": "^7.24.7",
"@babel/plugin-transform-runtime": "^7.24.7",
"@babel/preset-env": "^7.24.7",
"@babel/preset-react": "^7.24.7",
"@googleapis/drive": "^8.11.0",
"@babel/core": "^7.26.0",
"@babel/plugin-transform-runtime": "^7.25.9",
"@babel/preset-env": "^7.26.0",
"@babel/preset-react": "^7.26.3",
"@googleapis/drive": "^8.14.0",
"body-parser": "^1.20.2",
"classnames": "^2.5.1",
"codemirror": "^5.65.6",
"cookie-parser": "^1.4.6",
"cookie-parser": "^1.4.7",
"create-react-class": "^15.7.0",
"dedent-tabs": "^0.10.3",
"dompurify": "^3.1.5",
"dompurify": "^3.2.2",
"expr-eval": "^2.0.2",
"express": "^4.19.2",
"express": "^4.21.2",
"express-async-handler": "^1.2.0",
"express-static-gzip": "2.1.7",
"express-static-gzip": "2.2.0",
"fs-extra": "11.2.0",
"idb-keyval": "^6.2.1",
"js-yaml": "^4.1.0",
"jwt-simple": "^0.5.6",
"less": "^3.13.1",
"lodash": "^4.17.21",
"marked": "11.2.0",
"marked-emoji": "^1.4.1",
"marked-extended-tables": "^1.0.8",
"marked-emoji": "^1.4.3",
"marked-extended-tables": "^1.0.10",
"marked-gfm-heading-id": "^3.2.0",
"marked-smartypants-lite": "^1.0.2",
"markedLegacy": "npm:marked@^0.3.19",
"moment": "^2.30.1",
"mongoose": "^8.4.5",
"nanoid": "3.3.4",
"mongoose": "^8.8.3",
"nanoid": "5.0.9",
"nconf": "^0.12.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-frame-component": "^4.1.3",
"react-router-dom": "6.24.1",
"react-router-dom": "6.28.0",
"sanitize-filename": "1.6.3",
"superagent": "^9.0.2",
"superagent": "^10.1.1",
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
},
"devDependencies": {
"eslint": "^8.57.0",
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-react": "^7.34.3",
"@stylistic/stylelint-plugin": "^3.1.1",
"babel-plugin-transform-import-meta": "^2.2.1",
"eslint": "^9.16.0",
"eslint-plugin-jest": "^28.9.0",
"eslint-plugin-react": "^7.37.2",
"globals": "^15.13.0",
"jest": "^29.7.0",
"jest-expect-message": "^1.1.3",
"jsdom-global": "^3.0.2",
"postcss-less": "^6.0.0",
"stylelint": "^15.11.0",
"stylelint-config-recess-order": "^4.6.0",
"stylelint-config-recommended": "^13.0.0",
"stylelint-stylistic": "^0.4.3",
"stylelint": "^16.11.0",
"stylelint-config-recess-order": "^5.1.1",
"stylelint-config-recommended": "^14.0.1",
"supertest": "^7.0.0"
}
}

View File

@@ -1,13 +1,14 @@
const fs = require('fs-extra');
const Proj = require('./project.json');
const { pack } = require('vitreum');
import fs from 'fs-extra';
import Proj from './project.json' with { type: 'json' };
import vitreum from 'vitreum';
const { pack } = vitreum;
import lessTransform from 'vitreum/transforms/less.js';
import assetTransform from 'vitreum/transforms/asset.js';
const isDev = !!process.argv.find((arg)=>arg=='--dev');
const lessTransform = require('vitreum/transforms/less.js');
const assetTransform = require('vitreum/transforms/asset.js');
//const Meta = require('vitreum/headtags');
const transforms = {
'.less' : lessTransform,
'*' : assetTransform('./build')
@@ -17,7 +18,7 @@ const build = async ({ bundle, render, ssr })=>{
const css = await lessTransform.generate({ paths: './shared' });
await fs.outputFile('./build/admin/bundle.css', css);
await fs.outputFile('./build/admin/bundle.js', bundle);
await fs.outputFile('./build/admin/ssr.js', ssr);
await fs.outputFile('./build/admin/ssr.cjs', ssr);
};
fs.emptyDirSync('./build/admin');

View File

@@ -1,14 +1,15 @@
const fs = require('fs-extra');
const zlib = require('zlib');
const Proj = require('./project.json');
import fs from 'fs-extra';
import zlib from 'zlib';
import Proj from './project.json' with { type: 'json' };
import vitreum from 'vitreum';
const { pack, watchFile, livereload } = vitreum;
const { pack, watchFile, livereload } = require('vitreum');
const isDev = !!process.argv.find((arg)=>arg=='--dev');
import lessTransform from 'vitreum/transforms/less.js';
import assetTransform from 'vitreum/transforms/asset.js';
import babel from '@babel/core';
import less from 'less';
const lessTransform = require('vitreum/transforms/less.js');
const assetTransform = require('vitreum/transforms/asset.js');
const babel = require('@babel/core');
const less = require('less');
const isDev = !!process.argv.find((arg) => arg === '--dev');
const babelify = async (code)=>(await babel.transformAsync(code, { presets: [['@babel/preset-env', { 'exclude': ['proposal-dynamic-import'] }], '@babel/preset-react'], plugins: ['@babel/plugin-transform-runtime'] })).code;
@@ -24,7 +25,7 @@ const build = async ({ bundle, render, ssr })=>{
//css = `@layer bundle {\n${css}\n}`;
await fs.outputFile('./build/homebrew/bundle.css', css);
await fs.outputFile('./build/homebrew/bundle.js', bundle);
await fs.outputFile('./build/homebrew/ssr.js', ssr);
await fs.outputFile('./build/homebrew/ssr.cjs', ssr);
await fs.copy('./client/homebrew/favicon.ico', './build/assets/favicon.ico');
@@ -51,7 +52,7 @@ fs.emptyDirSync('./build');
const themes = { Legacy: {}, V3: {} };
let themeFiles = fs.readdirSync('./themes/Legacy');
for (dir of themeFiles) {
for (let dir of themeFiles) {
const themeData = JSON.parse(fs.readFileSync(`./themes/Legacy/${dir}/settings.json`).toString());
themeData.path = dir;
themes.Legacy[dir] = (themeData);
@@ -68,7 +69,7 @@ fs.emptyDirSync('./build');
}
themeFiles = fs.readdirSync('./themes/V3');
for (dir of themeFiles) {
for (let dir of themeFiles) {
const themeData = JSON.parse(fs.readFileSync(`./themes/V3/${dir}/settings.json`).toString());
themeData.path = dir;
themes.V3[dir] = (themeData);
@@ -104,14 +105,14 @@ fs.emptyDirSync('./build');
const editorThemesBuildDir = './build/homebrew/cm-themes';
await fs.copy('./node_modules/codemirror/theme', editorThemesBuildDir);
await fs.copy('./themes/codeMirror/customThemes', editorThemesBuildDir);
editorThemeFiles = fs.readdirSync(editorThemesBuildDir);
const editorThemeFiles = fs.readdirSync(editorThemesBuildDir);
const editorThemeFile = './themes/codeMirror/editorThemes.json';
if(fs.existsSync(editorThemeFile)) fs.rmSync(editorThemeFile);
const stream = fs.createWriteStream(editorThemeFile, { flags: 'a' });
stream.write('[\n"default"');
for (themeFile of editorThemeFiles) {
for (let themeFile of editorThemeFiles) {
stream.write(`,\n"${themeFile.slice(0, -4)}"`);
}
stream.write('\n]\n');

View File

@@ -1,12 +1,12 @@
const DB = require('./server/db.js');
const server = require('./server/app.js');
const config = require('./server/config.js');
import DB from './server/db.js';
import server from './server/app.js';
import config from './server/config.js';
DB.connect(config).then(()=>{
// Ensure that we have successfully connected to the database
// before launching server
const PORT = process.env.PORT || config.get('web_port') || 8000;
server.app.listen(PORT, ()=>{
server.listen(PORT, ()=>{
const reset = '\x1b[0m'; // Reset to default style
const bright = '\x1b[1m'; // Bright (bold) style
const cyan = '\x1b[36m'; // Cyan color

View File

@@ -1,9 +1,15 @@
const HomebrewModel = require('./homebrew.model.js').model;
const router = require('express').Router();
const Moment = require('moment');
//const render = require('vitreum/steps/render');
const templateFn = require('../client/template.js');
const zlib = require('zlib');
import {model as HomebrewModel } from './homebrew.model.js';
import {model as NotificationModel } from './notifications.model.js';
import express from 'express';
import Moment from 'moment';
import zlib from 'zlib';
import templateFn from '../client/template.js';
import HomebrewAPI from './homebrew.api.js';
import asyncHandler from 'express-async-handler';
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
const router = express.Router();
process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin';
process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3';
@@ -22,7 +28,7 @@ const mw = {
if(process.env.ADMIN_USER === username && process.env.ADMIN_PASS === password){
return next();
}
return res.status(401).send('Access denied');
throw { HBErrorCode: '52', code: 401, message: 'Access denied' };
}
};
@@ -66,23 +72,8 @@ router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{
});
/* Searches for matching edit or share id, also attempts to partial match */
router.get('/admin/lookup/:id', mw.adminOnly, async (req, res, next)=>{
HomebrewModel.findOne({
$or : [
{ editId: { $regex: req.params.id, $options: 'i' } },
{ shareId: { $regex: req.params.id, $options: 'i' } },
]
}).exec()
.then((brew)=>{
if(!brew) // No document found
return res.status(404).json({ error: 'Document not found' });
else
return res.json(brew);
})
.catch((err)=>{
console.error(err);
return res.status(500).json({ error: 'Internal Server Error' });
});
router.get('/admin/lookup/:id', mw.adminOnly, asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res, next)=>{
return res.json(req.brew);
});
/* Find 50 brews that aren't compressed yet */
@@ -100,6 +91,25 @@ router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{
});
});
/* Cleans `<script` and `</script>` from the "text" field of a brew */
router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res)=>{
console.log(`[ADMIN] Cleaning script tags from ShareID ${req.params.id}`);
function cleanText(text){return text.replaceAll(/(<\/?s)cript/gi, '');};
const brew = req.brew;
const properties = ['text', 'description', 'title'];
properties.forEach((property)=>{
brew[property] = cleanText(brew[property]);
});
splitTextStyleAndMetadata(brew);
req.body = brew;
return await HomebrewAPI.updateBrew(req, res);
});
/* Compresses the "text" field of a brew to binary */
router.put('/admin/compress/:id', (req, res)=>{
@@ -138,12 +148,48 @@ router.get('/admin/stats', mw.adminOnly, async (req, res)=>{
}
});
// ####################### NOTIFICATIONS
router.get('/admin/notification/all', async (req, res, next)=>{
try {
const notifications = await NotificationModel.getAll();
return res.json(notifications);
} catch (error) {
console.log('Error getting all notifications: ', error.message);
return res.status(500).json({ message: error.message });
}
});
router.post('/admin/notification/add', mw.adminOnly, async (req, res, next)=>{
try {
const notification = await NotificationModel.addNotification(req.body);
return res.status(201).json(notification);
} catch (error) {
console.log('Error adding notification: ', error.message);
return res.status(500).json({ message: error.message });
}
});
router.delete('/admin/notification/delete/:id', mw.adminOnly, async (req, res, next)=>{
try {
const notification = await NotificationModel.deleteNotification(req.params.id);
return res.json(notification);
} catch (error) {
console.error('Error deleting notification: { key: ', req.params.id, ' error: ', error.message, ' }');
return res.status(500).json({ message: error.message });
}
});
router.get('/admin', mw.adminOnly, (req, res)=>{
templateFn('admin', {
url : req.originalUrl
})
.then((page)=>res.send(page))
.catch((err)=>res.sendStatus(500));
.catch((err)=>{
console.log(err);
res.sendStatus(500);
});
});
module.exports = router;
export default router;

117
server/admin.api.spec.js Normal file
View File

@@ -0,0 +1,117 @@
import supertest from 'supertest';
import HBApp from './app.js';
import {model as NotificationModel } from './notifications.model.js';
// Mimic https responses to avoid being redirected all the time
const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https');
describe('Tests for admin api', ()=>{
afterEach(()=>{
jest.resetAllMocks();
});
describe('Notifications', ()=>{
it('should return list of all notifications', async ()=>{
const testNotifications = ['a', 'b'];
jest.spyOn(NotificationModel, 'find')
.mockImplementationOnce(() => {
return { exec: jest.fn().mockResolvedValue(testNotifications) };
});
const response = await app
.get('/admin/notification/all')
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`);
expect(response.status).toBe(200);
expect(response.body).toEqual(testNotifications);
});
it('should add a new notification', async ()=>{
const inputNotification = {
title : 'Test Notification',
text : 'This is a test notification',
startAt : new Date().toISOString(),
stopAt : new Date().toISOString(),
dismissKey : 'testKey'
};
const savedNotification = {
...inputNotification,
_id : expect.any(String),
createdAt : expect.any(String),
startAt : inputNotification.startAt,
stopAt : inputNotification.stopAt,
};
jest.spyOn(NotificationModel.prototype, 'save')
.mockImplementationOnce(function() {
return Promise.resolve(this);
});
const response = await app
.post('/admin/notification/add')
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`)
.send(inputNotification);
expect(response.status).toBe(201);
expect(response.body).toEqual(savedNotification);
});
it('should handle error adding a notification without dismissKey', async () => {
const inputNotification = {
title : 'Test Notification',
text : 'This is a test notification',
startAt : new Date().toISOString(),
stopAt : new Date().toISOString()
};
//Change 'save' function to just return itself instead of actually interacting with the database
jest.spyOn(NotificationModel.prototype, 'save')
.mockImplementationOnce(function() {
return Promise.resolve(this);
});
const response = await app
.post('/admin/notification/add')
.set('Authorization', 'Basic ' + Buffer.from('admin:password3').toString('base64'))
.send(inputNotification);
expect(response.status).toBe(500);
expect(response.body).toEqual({ message: 'Dismiss key is required!' });
});
it('should delete a notification based on its dismiss key', async ()=>{
const dismissKey = 'testKey';
jest.spyOn(NotificationModel, 'findOneAndDelete')
.mockImplementationOnce((key) => {
return { exec: jest.fn().mockResolvedValue(key) };
});
const response = await app
.delete(`/admin/notification/delete/${dismissKey}`)
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`);
expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({'dismissKey': 'testKey'});
expect(response.status).toBe(200);
expect(response.body).toEqual({ dismissKey: 'testKey' });
});
it('should handle error deleting a notification that doesnt exist', async ()=>{
const dismissKey = 'testKey';
jest.spyOn(NotificationModel, 'findOneAndDelete')
.mockImplementationOnce(() => {
return { exec: jest.fn().mockResolvedValue() };
});
const response = await app
.delete(`/admin/notification/delete/${dismissKey}`)
.set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`);
expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({'dismissKey': 'testKey'});
expect(response.status).toBe(500);
expect(response.body).toEqual({ message: 'Notification not found' });
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
const _ = require('lodash');
import _ from 'lodash';
// Default properties for newly-created brews
const DEFAULT_BREW = {
@@ -32,7 +32,7 @@ const DEFAULT_BREW_LOAD = _.defaults(
},
DEFAULT_BREW);
module.exports = {
export {
DEFAULT_BREW,
DEFAULT_BREW_LOAD
};

View File

@@ -1,5 +1,7 @@
module.exports = require('nconf')
.argv()
.env({ lowerCase: true })
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
.file('defaults', { file: 'config/default.json' });
import nconf from 'nconf';
export default nconf
.argv()
.env({ lowerCase: true })
.file('environment', { file: `config/${process.env.NODE_ENV}.json` })
.file('defaults', { file: 'config/default.json' });

View File

@@ -5,7 +5,7 @@
// reused by both the main application and all tests which require database
// connection.
const Mongoose = require('mongoose');
import Mongoose from 'mongoose';
const getMongoDBURL = (config)=>{
return config.get('mongodb_uri') ||
@@ -31,7 +31,7 @@ const connect = async (config)=>{
.catch((error)=>handleConnectionError(error));
};
module.exports = {
connect : connect,
disconnect : disconnect
export default {
connect,
disconnect
};

View File

@@ -1,4 +1,4 @@
module.exports = (req, res, next)=>{
export default (req, res, next)=>{
if(process.env.NODE_ENV === 'local' || process.env.NODE_ENV === 'docker') return next();
if(req.header('x-forwarded-proto') !== 'https') {
return res.redirect(302, `https://${req.get('Host')}${req.url}`);

View File

@@ -1,8 +1,9 @@
/* eslint-disable max-lines */
const googleDrive = require('@googleapis/drive');
const { nanoid } = require('nanoid');
const token = require('./token.js');
const config = require('./config.js');
import googleDrive from '@googleapis/drive';
import { nanoid } from 'nanoid';
import token from './token.js';
import config from './config.js';
let serviceAuth;
if(!config.get('service_account')){
@@ -25,6 +26,15 @@ if(!config.get('service_account')){
const defaultAuth = serviceAuth || config.get('google_api_key');
const retryConfig = {
retry: 3, // Number of retry attempts
retryDelay: 100, // Initial delay in milliseconds
retryDelayMultiplier: 2, // Multiplier for exponential backoff
maxRetryDelay: 32000, // Maximum delay in milliseconds
httpMethodsToRetry: ['PATCH'], // Only retry PATCH requests
statusCodesToRetry: [[429, 429]], // Only retry on 429 status code
};
const GoogleActions = {
authCheck : (account, res, updateTokens=true)=>{
@@ -50,7 +60,7 @@ const GoogleActions = {
account.googleRefreshToken = tokens.refresh_token;
}
account.googleAccessToken = tokens.access_token;
const JWTToken = token.generateAccessToken(account);
const JWTToken = token(account);
//Save updated token to cookie
//res.cookie('nc_session', JWTToken, { maxAge: 1000*60*60*24*365, path: '/', sameSite: 'lax' });
@@ -63,7 +73,7 @@ const GoogleActions = {
getGoogleFolder : async (auth)=>{
const drive = googleDrive.drive({ version: 'v3', auth });
fileMetadata = {
const fileMetadata = {
'name' : 'Homebrewery',
'mimeType' : 'application/vnd.google-apps.folder'
};
@@ -112,9 +122,7 @@ const GoogleActions = {
})
.catch((err)=>{
console.log(`Error Listing Google Brews`);
console.error(err);
throw (err);
//TODO: Should break out here, but continues on for some reason.
});
fileList.push(...obj.data.files);
NextPageToken = obj.data.nextPageToken;
@@ -147,7 +155,7 @@ const GoogleActions = {
return brews;
},
updateGoogleBrew : async (brew)=>{
updateGoogleBrew : async (brew, userIp)=>{
const drive = googleDrive.drive({ version: 'v3', auth: defaultAuth });
await drive.files.update({
@@ -168,11 +176,14 @@ const GoogleActions = {
media : {
mimeType : 'text/plain',
body : brew.text
}
},
headers: {
'X-Forwarded-For': userIp, // Set the X-Forwarded-For header
},
retryConfig
})
.catch((err)=>{
console.log('Error saving to google');
console.error(err);
throw (err);
});
@@ -211,7 +222,6 @@ const GoogleActions = {
})
.catch((err)=>{
console.log('Error while creating new Google brew');
console.error(err);
throw (err);
});
@@ -231,8 +241,8 @@ const GoogleActions = {
return obj.data.id;
},
getGoogleBrew : async (id, accessId, accessType)=>{
const drive = googleDrive.drive({ version: 'v3', auth: defaultAuth });
getGoogleBrew : async (auth = defaultAuth, id, accessId, accessType)=>{
const drive = googleDrive.drive({ version: 'v3', auth: auth });
const obj = await drive.files.get({
fileId : id,
@@ -335,4 +345,4 @@ const GoogleActions = {
}
};
module.exports = GoogleActions;
export default GoogleActions;

View File

@@ -1,15 +1,24 @@
/* eslint-disable max-lines */
const _ = require('lodash');
const HomebrewModel = require('./homebrew.model.js').model;
const router = require('express').Router();
const zlib = require('zlib');
const GoogleActions = require('./googleActions.js');
const Markdown = require('../shared/naturalcrit/markdown.js');
const yaml = require('js-yaml');
const asyncHandler = require('express-async-handler');
const { nanoid } = require('nanoid');
import _ from 'lodash';
import {model as HomebrewModel} from './homebrew.model.js';
import express from 'express';
import zlib from 'zlib';
import GoogleActions from './googleActions.js';
import Markdown from '../shared/naturalcrit/markdown.js';
import yaml from 'js-yaml';
import asyncHandler from 'express-async-handler';
import { nanoid } from 'nanoid';
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
import checkClientVersion from './middleware/check-client-version.js';
const { DEFAULT_BREW, DEFAULT_BREW_LOAD } = require('./brewDefaults.js');
const router = express.Router();
import { DEFAULT_BREW, DEFAULT_BREW_LOAD } from './brewDefaults.js';
import Themes from '../themes/themes.json' with { type: 'json' };
const isStaticTheme = (renderer, themeName)=>{
return Themes[renderer]?.[themeName] !== undefined;
};
// const getTopBrews = (cb) => {
// HomebrewModel.find().sort({ views: -1 }).limit(5).exec(function(err, brews) {
@@ -37,73 +46,126 @@ const api = {
}
return { id, googleId };
},
//Get array of any of this user's brews tagged with `meta:theme`
getUsersBrewThemes : async (username)=>{
if(!username)
return {};
const fields = [
'title',
'tags',
'shareId',
'thumbnail',
'textBin',
'text',
'authors',
'renderer'
];
const userThemes = {};
const brews = await HomebrewModel.getByUser(username, true, fields, { tags: { $in: ['meta:theme', 'meta:Theme'] } });
if(brews) {
for (const brew of brews) {
userThemes[brew.renderer] ??= {};
userThemes[brew.renderer][brew.shareId] = {
name : brew.title,
renderer : brew.renderer,
baseTheme : brew.theme,
baseSnippets : false,
author : brew.authors[0],
path : brew.shareId,
thumbnail : brew.thumbnail || '/assets/naturalCritLogoWhite.svg'
};
}
}
return userThemes;
},
getBrew : (accessType, stubOnly = false)=>{
// Create middleware with the accessType passed in as part of the scope
return async (req, res, next)=>{
// Get relevant IDs for the brew
const { id, googleId } = api.getId(req);
let { id, googleId } = api.getId(req);
const accessMap = {
edit : { editId: id },
share : { shareId: id },
admin : { $or : [{ editId: id }, { shareId: id }] }
};
// Try to find the document in the Homebrewery database -- if it doesn't exist, that's fine.
let stub = await HomebrewModel.get(accessType === 'edit' ? { editId: id } : { shareId: id })
let stub = await HomebrewModel.get(accessMap[accessType])
.catch((err)=>{
if(googleId) {
if(googleId)
console.warn(`Unable to find document stub for ${accessType}Id ${id}`);
} else {
else
console.warn(err);
}
});
stub = stub?.toObject();
googleId ??= stub?.googleId;
const isOwner = stub?.authors?.length === 0 || stub?.authors?.[0] === req.account?.username;
const isAuthor = stub?.authors?.includes(req.account?.username);
const isInvited = stub?.invitedAuthors?.includes(req.account?.username);
if(accessType === 'edit' && !(isOwner || isAuthor || isInvited)) {
const accessError = { name: 'Access Error', status: 401, authors: stub.authors, brewTitle: stub.title, shareId: stub.shareId };
if(req.account)
throw { ...accessError, message: 'User is not an Author', HBErrorCode: '03' };
else
throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04' };
}
if(stub?.lock?.locked && accessType != 'edit') {
throw { HBErrorCode: '100', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title };
throw { HBErrorCode: '51', code: stub.lock.code, message: stub.lock.shareMessage, brewId: stub.shareId, brewTitle: stub.title };
}
// If there is a google id, try to find the google brew
if(!stubOnly && (googleId || stub?.googleId)) {
let googleError;
const googleBrew = await GoogleActions.getGoogleBrew(googleId || stub?.googleId, id, accessType)
.catch((err)=>{
googleError = err;
if(!stubOnly && googleId) {
const oAuth2Client = isOwner? GoogleActions.authCheck(req.account, res) : undefined;
const googleBrew = await GoogleActions.getGoogleBrew(oAuth2Client, googleId, id, accessType)
.catch((googleError)=>{
const reason = googleError.errors?.[0].reason;
if(reason == 'notFound')
throw { ...googleError, HBErrorCode: '02', authors: stub?.authors, account: req.account?.username };
else
throw { ...googleError, HBErrorCode: '01' };
});
// Throw any error caught while attempting to retrieve Google brew.
if(googleError) {
const reason = googleError.errors?.[0].reason;
if(reason == 'notFound') {
throw { ...googleError, HBErrorCode: '02', authors: stub?.authors, account: req.account?.username };
} else {
throw { ...googleError, HBErrorCode: '01' };
}
}
// Combine the Homebrewery stub with the google brew, or if the stub doesn't exist just use the google brew
stub = stub ? _.assign({ ...api.excludeStubProps(stub), stubbed: true }, api.excludeGoogleProps(googleBrew)) : googleBrew;
}
const authorsExist = stub?.authors?.length > 0;
const isAuthor = stub?.authors?.includes(req.account?.username);
const isInvited = stub?.invitedAuthors?.includes(req.account?.username);
if(accessType === 'edit' && (authorsExist && !(isAuthor || isInvited))) {
const accessError = { name: 'Access Error', status: 401 };
if(req.account){
throw { ...accessError, message: 'User is not an Author', HBErrorCode: '03', authors: stub.authors, brewTitle: stub.title, shareId: stub.shareId };
}
throw { ...accessError, message: 'User is not logged in', HBErrorCode: '04', authors: stub.authors, brewTitle: stub.title, shareId: stub.shareId };
}
// If after all of that we still don't have a brew, throw an exception
if(!stub && !stubOnly) {
if(!stub)
throw { name: 'BrewLoad Error', message: 'Brew not found', status: 404, HBErrorCode: '05', accessType: accessType, brewId: id };
}
// Clean up brew: fill in missing fields with defaults / fix old invalid values
if(stub) {
stub.tags = stub.tags || undefined; // Clear empty strings
stub.renderer = stub.renderer || undefined; // Clear empty strings
stub = _.defaults(stub, DEFAULT_BREW_LOAD); // Fill in blank fields
}
stub.tags = stub.tags || undefined; // Clear empty strings
stub.renderer = stub.renderer || undefined; // Clear empty strings
stub = _.defaults(stub, DEFAULT_BREW_LOAD); // Fill in blank fields
req.brew = stub ?? {};
req.brew = stub;
next();
};
},
getCSS : async (req, res)=>{
const { brew } = req;
if(!brew) return res.status(404).send('');
splitTextStyleAndMetadata(brew);
if(!brew.style) return res.status(404).send('');
res.set({
'Cache-Control' : 'no-cache',
'Content-Type' : 'text/css'
});
return res.status(200).send(brew.style);
},
mergeBrewText : (brew)=>{
let text = brew.text;
if(brew.style !== undefined) {
@@ -142,7 +204,7 @@ const api = {
return modified;
},
excludeStubProps : (brew)=>{
const propsToExclude = ['text', 'textBin', 'renderer', 'pageCount'];
const propsToExclude = ['text', 'textBin'];
for (const prop of propsToExclude) {
brew[prop] = undefined;
}
@@ -184,11 +246,8 @@ const api = {
let googleId, saved;
if(saveToGoogle) {
googleId = await api.newGoogleBrew(req.account, newHomebrew, res)
.catch((err)=>{
console.error(err);
res.status(err?.status || err?.response?.status || 500).send(err?.message || err);
});
googleId = await api.newGoogleBrew(req.account, newHomebrew, res);
if(!googleId) return;
api.excludeStubProps(newHomebrew);
newHomebrew.googleId = googleId;
@@ -209,6 +268,57 @@ const api = {
res.status(200).send(saved);
},
getThemeBundle : async(req, res)=>{
/* getThemeBundle: Collects the theme and all parent themes
returns an object containing an array of css, and an array of snippets, in render order
req.params.id : The shareId ( User theme ) or name ( static theme )
req.params.renderer : The Markdown renderer used for this theme */
req.params.renderer = _.upperFirst(req.params.renderer);
let currentTheme;
const completeStyles = [];
const completeSnippets = [];
while (req.params.id) {
//=== User Themes ===//
if(!isStaticTheme(req.params.renderer, req.params.id)) {
await api.getBrew('share')(req, res, ()=>{})
.catch((err)=>{
if(err.HBErrorCode == '05')
err = { ...err, name: 'ThemeLoad Error', message: 'Theme Not Found', HBErrorCode: '09' };
throw err;
});
currentTheme = req.brew;
splitTextStyleAndMetadata(currentTheme);
// If there is anything in the snippets or style members, append them to the appropriate array
if(currentTheme?.snippets) completeSnippets.push(JSON.parse(currentTheme.snippets));
if(currentTheme?.style) completeStyles.push(`/* From Brew: ${req.protocol}://${req.get('host')}/share/${req.params.id} */\n\n${currentTheme.style}`);
req.params.id = currentTheme.theme;
req.params.renderer = currentTheme.renderer;
} else {
//=== Static Themes ===//
const localSnippets = `${req.params.renderer}_${req.params.id}`; // Just log the name for loading on client
const localStyle = `@import url(\"/themes/${req.params.renderer}/${req.params.id}/style.css\");`;
completeSnippets.push(localSnippets);
completeStyles.push(`/* From Theme ${req.params.id} */\n\n${localStyle}`);
req.params.id = Themes[req.params.renderer][req.params.id].baseTheme;
}
}
const returnObj = {
// Reverse the order of the arrays so they are listed oldest parent to youngest child.
styles : completeStyles.reverse(),
snippets : completeSnippets.reverse()
};
res.setHeader('Content-Type', 'application/json');
return res.status(200).send(returnObj);
},
updateBrew : async (req, res)=>{
// Initialize brew from request and body, destructure query params, and set the initial value for the after-save method
const brewFromClient = api.excludePropsFromUpdate(req.body);
@@ -241,19 +351,13 @@ const api = {
brew.googleId = undefined;
} else if(!brew.googleId && saveToGoogle) {
// If we don't have a google id and the user wants to save to google, create the google brew and set the google id on the brew
brew.googleId = await api.newGoogleBrew(req.account, api.excludeGoogleProps(brew), res)
.catch((err)=>{
console.error(err);
res.status(err.status || err.response.status).send(err.message || err);
});
brew.googleId = await api.newGoogleBrew(req.account, api.excludeGoogleProps(brew), res);
if(!brew.googleId) return;
} else if(brew.googleId) {
// If the google id exists and no other actions are being performed, update the google brew
const updated = await GoogleActions.updateGoogleBrew(api.excludeGoogleProps(brew))
.catch((err)=>{
console.error(err);
res.status(err?.response?.status || 500).send(err);
});
const updated = await GoogleActions.updateGoogleBrew(api.excludeGoogleProps(brew), req.ip);
if(!updated) return;
}
@@ -363,11 +467,12 @@ const api = {
}
};
router.use('/api', require('./middleware/check-client-version.js'));
router.use('/api', checkClientVersion);
router.post('/api', asyncHandler(api.newBrew));
router.put('/api/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
router.put('/api/update/:id', asyncHandler(api.getBrew('edit', true)), asyncHandler(api.updateBrew));
router.delete('/api/:id', asyncHandler(api.deleteBrew));
router.get('/api/remove/:id', asyncHandler(api.deleteBrew));
router.get('/api/theme/:renderer/:id', asyncHandler(api.getThemeBundle));
module.exports = api;
export default api;

View File

@@ -1,5 +1,7 @@
/* eslint-disable max-lines */
import { splitTextStyleAndMetadata } from '../shared/helpers.js';
describe('Tests for api', ()=>{
let api;
let google;
@@ -14,6 +16,9 @@ describe('Tests for api', ()=>{
let saved;
beforeEach(()=>{
jest.resetModules();
jest.restoreAllMocks();
saved = undefined;
saveFunc = jest.fn(async function() {
saved = { ...this, _id: '1' };
@@ -33,8 +38,9 @@ describe('Tests for api', ()=>{
}
});
google = require('./googleActions.js');
model = require('./homebrew.model.js').model;
google = require('./googleActions.js').default;
model = require('./homebrew.model.js').model;
api = require('./homebrew.api').default;
jest.mock('./googleActions.js');
google.authCheck = jest.fn(()=>'client');
@@ -45,12 +51,12 @@ describe('Tests for api', ()=>{
model.mockImplementation((brew)=>modelBrew(brew));
res = {
status : jest.fn(()=>res),
send : jest.fn(()=>{})
status : jest.fn(()=>res),
send : jest.fn(()=>{}),
set : jest.fn(()=>{}),
setHeader : jest.fn(()=>{})
};
api = require('./homebrew.api');
hbBrew = {
text : `brew text`,
style : 'hello yes i am css',
@@ -81,10 +87,6 @@ describe('Tests for api', ()=>{
};
});
afterEach(()=>{
jest.restoreAllMocks();
});
describe('getId', ()=>{
it('should return only id if google id is not present', ()=>{
const { id, googleId } = api.getId({
@@ -296,7 +298,7 @@ describe('Tests for api', ()=>{
expect(next).toHaveBeenCalled();
expect(api.getId).toHaveBeenCalledWith(req);
expect(model.get).toHaveBeenCalledWith({ shareId: '1' });
expect(google.getGoogleBrew).toHaveBeenCalledWith('2', '1', 'share');
expect(google.getGoogleBrew).toHaveBeenCalledWith(undefined, '2', '1', 'share');
});
it('access is denied to a locked brew', async()=>{
@@ -308,7 +310,7 @@ describe('Tests for api', ()=>{
const req = { brew: {} };
const next = jest.fn();
await expect(fn(req, null, next)).rejects.toEqual({ 'HBErrorCode': '100', 'brewId': '1', 'brewTitle': 'test brew', 'code': 404, 'message': 'brew locked' });
await expect(fn(req, null, next)).rejects.toEqual({ 'HBErrorCode': '51', 'brewId': '1', 'brewTitle': 'test brew', 'code': 404, 'message': 'brew locked' });
});
});
@@ -408,8 +410,8 @@ brew`);
expect(sent).not.toEqual(googleBrew);
expect(result.text).toBeUndefined();
expect(result.textBin).toBeUndefined();
expect(result.renderer).toBeUndefined();
expect(result.pageCount).toBeUndefined();
expect(result.renderer).toBe('v3');
expect(result.pageCount).toBe(1);
});
});
@@ -540,9 +542,9 @@ brew`);
description : '',
editId : expect.any(String),
gDrive : false,
pageCount : undefined,
pageCount : 1,
published : false,
renderer : undefined,
renderer : 'V3',
lang : 'en',
shareId : expect.any(String),
googleId : expect.any(String),
@@ -559,16 +561,6 @@ brew`);
views : 0
});
});
it('should handle google error', async()=>{
google.newGoogleBrew = jest.fn(()=>{
throw 'err';
});
await api.newBrew({ body: { text: 'asdf', title: '' }, query: { saveToGoogle: true }, account: { username: 'test user' } }, res);
expect(res.status).toHaveBeenCalledWith(500);
expect(res.send).toHaveBeenCalledWith('err');
});
});
describe('deleteGoogleBrew', ()=>{
@@ -581,6 +573,121 @@ brew`);
});
});
describe('Theme bundle', ()=>{
it('should return Theme Bundle for a User Theme', async ()=>{
const brews = {
userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: null, shareId: 'userThemeAID', style: 'User Theme A Style' }
};
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
model.get = jest.fn((getParams)=>toBrewPromise(brews[getParams.shareId]));
const req = { params: { renderer: 'V3', id: 'userThemeAID' }, get: ()=>{ return 'localhost'; }, protocol: 'https' };
await api.getThemeBundle(req, res);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.send).toHaveBeenCalledWith({
styles : ['/* From Brew: https://localhost/share/userThemeAID */\n\nUser Theme A Style'],
snippets : []
});
});
it('should return Theme Bundle for nested User Themes', async ()=>{
const brews = {
userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'userThemeBID', shareId: 'userThemeAID', style: 'User Theme A Style' },
userThemeBID : { title: 'User Theme B', renderer: 'V3', theme: 'userThemeCID', shareId: 'userThemeBID', style: 'User Theme B Style' },
userThemeCID : { title: 'User Theme C', renderer: 'V3', theme: null, shareId: 'userThemeCID', style: 'User Theme C Style' }
};
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
model.get = jest.fn((getParams)=>toBrewPromise(brews[getParams.shareId]));
const req = { params: { renderer: 'V3', id: 'userThemeAID' }, get: ()=>{ return 'localhost'; }, protocol: 'https' };
await api.getThemeBundle(req, res);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.send).toHaveBeenCalledWith({
styles : [
'/* From Brew: https://localhost/share/userThemeCID */\n\nUser Theme C Style',
'/* From Brew: https://localhost/share/userThemeBID */\n\nUser Theme B Style',
'/* From Brew: https://localhost/share/userThemeAID */\n\nUser Theme A Style'
],
snippets : []
});
});
it('should return Theme Bundle for a Static Theme', async ()=>{
const req = { params: { renderer: 'V3', id: '5ePHB' }, get: ()=>{ return 'localhost'; }, protocol: 'https' };
await api.getThemeBundle(req, res);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.send).toHaveBeenCalledWith({
styles : [
`/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`,
`/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");`
],
snippets : [
'V3_Blank',
'V3_5ePHB'
]
});
});
it('should return Theme Bundle for nested User and Static Themes together', async ()=>{
const brews = {
userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'userThemeBID', shareId: 'userThemeAID', style: 'User Theme A Style' },
userThemeBID : { title: 'User Theme B', renderer: 'V3', theme: 'userThemeCID', shareId: 'userThemeBID', style: 'User Theme B Style' },
userThemeCID : { title: 'User Theme C', renderer: 'V3', theme: '5eDMG', shareId: 'userThemeCID', style: 'User Theme C Style' }
};
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
model.get = jest.fn((getParams)=>toBrewPromise(brews[getParams.shareId]));
const req = { params: { renderer: 'V3', id: 'userThemeAID' }, get: ()=>{ return 'localhost'; }, protocol: 'https' };
await api.getThemeBundle(req, res);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.send).toHaveBeenCalledWith({
styles : [
`/* From Theme Blank */\n\n@import url("/themes/V3/Blank/style.css");`,
`/* From Theme 5ePHB */\n\n@import url("/themes/V3/5ePHB/style.css");`,
`/* From Theme 5eDMG */\n\n@import url("/themes/V3/5eDMG/style.css");`,
'/* From Brew: https://localhost/share/userThemeCID */\n\nUser Theme C Style',
'/* From Brew: https://localhost/share/userThemeBID */\n\nUser Theme B Style',
'/* From Brew: https://localhost/share/userThemeAID */\n\nUser Theme A Style'
],
snippets : [
'V3_Blank',
'V3_5ePHB',
'V3_5eDMG'
]
});
});
it('should fail for an invalid Theme in the chain', async()=>{
const brews = {
userThemeAID : { title: 'User Theme A', renderer: 'V3', theme: 'missingTheme', shareId: 'userThemeAID', style: 'User Theme A Style' },
};
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
model.get = jest.fn((getParams)=>toBrewPromise(brews[getParams.shareId]));
const req = { params: { renderer: 'V3', id: 'userThemeAID' }, get: ()=>{ return 'localhost'; }, protocol: 'https' };
let err;
await api.getThemeBundle(req, res)
.catch((e)=>err = e);
expect(err).toEqual({
HBErrorCode : '09',
accessType : 'share',
brewId : 'missingTheme',
message : 'Theme Not Found',
name : 'ThemeLoad Error',
status : 404 });
});
});
describe('deleteBrew', ()=>{
it('should handle case where fetching the brew returns an error', async ()=>{
api.getBrew = jest.fn(()=>async ()=>{ throw { message: 'err', HBErrorCode: '02' }; });
@@ -801,4 +908,119 @@ brew`);
expect(saved.googleId).toEqual(brew.googleId);
});
});
describe('Get CSS', ()=>{
it('should return brew style content as CSS text', async ()=>{
const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n````\n\n' };
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
model.get = jest.fn(()=>toBrewPromise(testBrew));
const fn = api.getBrew('share', true);
const req = { brew: {} };
const next = jest.fn();
await fn(req, null, next);
await api.getCSS(req, res);
expect(req.brew).toEqual(testBrew);
expect(req.brew).toHaveProperty('style', '\nI Have a style!\n');
expect(res.status).toHaveBeenCalledWith(200);
expect(res.send).toHaveBeenCalledWith('\nI Have a style!\n');
expect(res.set).toHaveBeenCalledWith({
'Cache-Control' : 'no-cache',
'Content-Type' : 'text/css'
});
});
it('should return 404 when brew has no style content', async ()=>{
const testBrew = { title: 'test brew', text: 'I don\'t have a style!' };
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
model.get = jest.fn(()=>toBrewPromise(testBrew));
const fn = api.getBrew('share', true);
const req = { brew: {} };
const next = jest.fn();
await fn(req, null, next);
await api.getCSS(req, res);
expect(req.brew).toEqual(testBrew);
expect(req.brew).toHaveProperty('style');
expect(res.status).toHaveBeenCalledWith(404);
expect(res.send).toHaveBeenCalledWith('');
});
it('should return 404 when brew does not exist', async ()=>{
const testBrew = { };
const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew }));
api.getId = jest.fn(()=>({ id: '1', googleId: undefined }));
model.get = jest.fn(()=>toBrewPromise(testBrew));
const fn = api.getBrew('share', true);
const req = { brew: {} };
const next = jest.fn();
await fn(req, null, next);
await api.getCSS(req, res);
expect(req.brew).toEqual(testBrew);
expect(req.brew).toHaveProperty('style');
expect(res.status).toHaveBeenCalledWith(404);
expect(res.send).toHaveBeenCalledWith('');
});
});
describe('Split Text, Style, and Metadata', ()=>{
it('basic splitting', async ()=>{
const testBrew = {
text : '```metadata\n' +
'title: title\n' +
'description: description\n' +
'tags: [ \'tag a\' , \'tag b\' ]\n' +
'systems: [ test system ]\n' +
'renderer: legacy\n' +
'theme: 5ePHB\n' +
'lang: en\n' +
'\n' +
'```\n' +
'\n' +
'```css\n' +
'style\n' +
'style\n' +
'style\n' +
'```\n' +
'\n' +
'text\n'
};
splitTextStyleAndMetadata(testBrew);
// Metadata
expect(testBrew.title).toEqual('title');
expect(testBrew.description).toEqual('description');
expect(testBrew.tags).toEqual(['tag a', 'tag b']);
expect(testBrew.systems).toEqual(['test system']);
expect(testBrew.renderer).toEqual('legacy');
expect(testBrew.theme).toEqual('5ePHB');
expect(testBrew.lang).toEqual('en');
// Style
expect(testBrew.style).toEqual('style\nstyle\nstyle');
// Text
expect(testBrew.text).toEqual('text\n');
});
it('convert tags string to array', async ()=>{
const testBrew = {
text : '```metadata\n' +
'tags: tag a\n' +
'```\n\n'
};
splitTextStyleAndMetadata(testBrew);
// Metadata
expect(testBrew.tags).toEqual(['tag a']);
});
});
});

View File

@@ -1,7 +1,8 @@
const mongoose = require('mongoose');
const { nanoid } = require('nanoid');
const _ = require('lodash');
const zlib = require('zlib');
import mongoose from 'mongoose';
import { nanoid } from 'nanoid';
import _ from 'lodash';
import zlib from 'zlib';
const HomebrewSchema = mongoose.Schema({
shareId : { type: String, default: ()=>{return nanoid(12);}, index: { unique: true } },
@@ -44,14 +45,14 @@ HomebrewSchema.statics.get = async function(query, fields=null){
const brew = await Homebrew.findOne(query, fields).orFail()
.catch((error)=>{throw 'Can not find brew';});
if(!_.isNil(brew.textBin)) { // Uncompress zipped text field
unzipped = zlib.inflateRawSync(brew.textBin);
const unzipped = zlib.inflateRawSync(brew.textBin);
brew.text = unzipped.toString();
}
return brew;
};
HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, fields=null){
const query = { authors: username, published: true };
HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, fields=null, filter=null){
const query = { authors: username, published: true, ...filter };
if(allowAccess){
delete query.published;
}
@@ -62,7 +63,7 @@ HomebrewSchema.statics.getByUser = async function(username, allowAccess=false, f
const Homebrew = mongoose.model('Homebrew', HomebrewSchema);
module.exports = {
schema : HomebrewSchema,
model : Homebrew,
export {
HomebrewSchema as schema,
Homebrew as model
};

View File

@@ -1,6 +1,8 @@
module.exports = (req, res, next)=>{
import packageJSON from '../../package.json' with { type: "json" };
const version = packageJSON.version;
export default (req, res, next)=>{
const userVersion = req.get('Homebrewery-Version');
const version = require('../../package.json').version;
if(userVersion != version) {
return res.status(412).send({

View File

@@ -1,12 +1,16 @@
module.exports = (req, res, next)=>{
import config from '../config.js';
const nodeEnv = config.get('node_env');
const isLocalEnvironment = config.get('local_environments').includes(nodeEnv);
export default (req, res, next)=>{
const isImageRequest = req.get('Accept')?.split(',')
?.filter((h)=>!h.includes('q='))
?.every((h)=>/image\/.*/.test(h));
if(isImageRequest) {
if(isImageRequest && !isLocalEnvironment && !req.url?.startsWith('/staticImages')) {
return res.status(406).send({
message : 'Request for image at this URL is not supported'
});
}
next();
};
};

Some files were not shown because too many files have changed in this diff Show More