diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 405431059..3d7236286 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -43,6 +43,7 @@ export { default as PostTooltip } from '../src/javascripts/post_tooltips.js'; export { default as PostVersion } from '../src/javascripts/post_version.js'; export { default as RelatedTag } from '../src/javascripts/related_tag.js'; export { default as Shortcuts } from '../src/javascripts/shortcuts.js'; +export { default as TagCounter } from '../src/javascripts/tag_counter.js'; export { default as Upload } from '../src/javascripts/uploads.js.erb'; export { default as UserTooltip } from '../src/javascripts/user_tooltips.js'; export { default as Utility } from '../src/javascripts/utility.js'; diff --git a/app/javascript/src/javascripts/posts.js.erb b/app/javascript/src/javascripts/posts.js.erb index 3ed6c68ed..c85b9c6dc 100644 --- a/app/javascript/src/javascripts/posts.js.erb +++ b/app/javascript/src/javascripts/posts.js.erb @@ -42,8 +42,6 @@ Post.initialize_all = function() { } var $fields_multiple = $('[data-autocomplete="tag-edit"]'); - $fields_multiple.on("keypress.danbooru", Post.update_tag_count); - $fields_multiple.on("click", Post.update_tag_count); $(window).on('danbooru:initialize_saved_seraches', () => { Post.initialize_saved_searches(); @@ -402,7 +400,6 @@ Post.initialize_post_sections = function() { $("#post_tag_string").focus().selectEnd().height($("#post_tag_string")[0].scrollHeight); $("#recommended").hide(); $(document).trigger("danbooru:open-post-edit-tab"); - Post.update_tag_count({target: $("#post_tag_string")}); } else if (e.target.hash === "#recommended") { $("#comments").hide(); $("#edit").hide(); @@ -513,32 +510,6 @@ Post.initialize_recommended = function() { }); }; -Post.update_tag_count = function(event) { - let string = "0 tags"; - let count = 0; - - if (event) { - let tags = Utility.regexp_split($(event.target).val()); - if (tags.length) { - count = tags.length; - string = (count === 1) ? (count + " tag") : (count + " tags") - } - } - - $("#tags-container .count").html(string); - let klass = ""; - - if (count < Post.LOW_TAG_COUNT) { - klass = "frown"; - } else if (count >= Post.LOW_TAG_COUNT && count < Post.HIGH_TAG_COUNT) { - klass = "meh"; - } else { - klass = "smile"; - } - - $("#tags-container .options #face").removeClass().addClass(`far fa-${klass}`); -} - $(document).ready(function() { Post.initialize_all(); }); diff --git a/app/javascript/src/javascripts/tag_counter.js b/app/javascript/src/javascripts/tag_counter.js new file mode 100644 index 000000000..3aa537cf7 --- /dev/null +++ b/app/javascript/src/javascripts/tag_counter.js @@ -0,0 +1,49 @@ +import { h, Component, render } from "preact"; +import { observable, computed, action } from "mobx"; +import { observer } from "mobx-react"; + +import Utility from "./utility"; + +export default @observer class TagCounter extends Component { + static lowCount = 10; + static highCount = 20; + + @observable tagCount = 0; + + componentDidMount() { + $(this.props.tags).on("input", this.updateCount); + this.updateCount(); + } + + render() { + return ( + + {this.tagCount} / {TagCounter.highCount} tags + + + ); + } + + @action.bound updateCount() { + this.tagCount = Utility.regexp_split($(this.props.tags).val()).length; + } + + @computed get emoji() { + if (this.tagCount < TagCounter.lowCount) { + return "frown"; + } else if (this.tagCount >= TagCounter.lowCount && this.tagCount < TagCounter.highCount) { + return "meh"; + } else { + return "smile"; + } + } + + static initialize() { + $("[data-tag-counter]").toArray().forEach(element => { + let target = $($(element).attr("data-for")).get(0); + render(h(TagCounter, { tags: target }), element); + }); + } +} + +$(TagCounter.initialize); diff --git a/app/views/posts/partials/show/_edit.html.erb b/app/views/posts/partials/show/_edit.html.erb index 93a07e9d6..6df702965 100644 --- a/app/views/posts/partials/show/_edit.html.erb +++ b/app/views/posts/partials/show/_edit.html.erb @@ -50,8 +50,7 @@ <%= f.label :tag_string, "Tags" %> - - + diff --git a/app/views/uploads/new.html.erb b/app/views/uploads/new.html.erb index c34bdaf92..8bc5b0fc1 100644 --- a/app/views/uploads/new.html.erb +++ b/app/views/uploads/new.html.erb @@ -66,8 +66,7 @@ <%= f.label :tag_string, "Tags" %> - - + diff --git a/babel.config.js b/babel.config.js index 12f98da5a..2f5c9da10 100644 --- a/babel.config.js +++ b/babel.config.js @@ -41,6 +41,13 @@ module.exports = function(api) { '@babel/plugin-syntax-dynamic-import', isTestEnv && 'babel-plugin-dynamic-import-node', '@babel/plugin-transform-destructuring', + ["@babel/plugin-proposal-decorators", { + legacy: true + }], + ["@babel/plugin-transform-react-jsx", { + pragma: "h", + pragmaFrag: "Fragment", + }], [ '@babel/plugin-proposal-class-properties', { diff --git a/config/webpack/environment.js b/config/webpack/environment.js index 607382c5e..1cb4e0d86 100644 --- a/config/webpack/environment.js +++ b/config/webpack/environment.js @@ -7,7 +7,9 @@ environment.loaders.append('erb', erb); environment.config.output.library = ["Danbooru"]; environment.config.set("resolve.alias", { - "jquery": "jquery/src/jquery.js" + "jquery": "jquery/src/jquery.js", + "react": "preact/compat", + "react-dom": "preact/compat", }); module.exports = environment diff --git a/package.json b/package.json index 66940300e..c396790fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,8 @@ { "license": "MIT", "dependencies": { + "@babel/plugin-proposal-decorators": "^7.10.5", + "@babel/plugin-transform-react-jsx": "^7.10.4", "@fortawesome/fontawesome-free": "^5.11.2", "@rails/ujs": "^6.0.2-1", "@rails/webpacker": "^5.0.0", @@ -9,6 +11,9 @@ "jquery": "3.5.1", "jquery-hotkeys": "^0.2.2", "jquery-ui": "^1.12.1", + "mobx": "^5.15.4", + "mobx-react": "^6.2.5", + "preact": "^10.4.6", "rails-erb-loader": "^5.5.0", "spark-md5": "^3.0.0", "tippy.js": "^6.2.3", diff --git a/yarn.lock b/yarn.lock index 3a219010c..925a17179 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,6 +65,23 @@ "@babel/helper-explode-assignable-expression" "^7.10.4" "@babel/types" "^7.10.4" +"@babel/helper-builder-react-jsx-experimental@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz#f35e956a19955ff08c1258e44a515a6d6248646b" + integrity sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/types" "^7.10.5" + +"@babel/helper-builder-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" + integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/types" "^7.10.4" + "@babel/helper-compilation-targets@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" @@ -88,6 +105,18 @@ "@babel/helper-replace-supers" "^7.10.4" "@babel/helper-split-export-declaration" "^7.10.4" +"@babel/helper-create-class-features-plugin@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" + integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.5" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-create-regexp-features-plugin@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" @@ -144,6 +173,13 @@ dependencies: "@babel/types" "^7.10.4" +"@babel/helper-member-expression-to-functions@^7.10.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" + integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== + dependencies: + "@babel/types" "^7.11.0" + "@babel/helper-module-imports@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" @@ -274,6 +310,15 @@ "@babel/helper-create-class-features-plugin" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-proposal-decorators@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz#42898bba478bc4b1ae242a703a953a7ad350ffb4" + integrity sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-decorators" "^7.10.4" + "@babel/plugin-proposal-dynamic-import@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" @@ -361,6 +406,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-syntax-decorators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz#6853085b2c429f9d322d02f5a635018cdeb2360c" + integrity sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -375,6 +427,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz#39abaae3cbf710c4373d8429484e6ba21340166c" + integrity sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" @@ -602,6 +661,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-transform-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz#673c9f913948764a4421683b2bef2936968fddf2" + integrity sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A== + dependencies: + "@babel/helper-builder-react-jsx" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" + "@babel/plugin-transform-regenerator@^7.10.4", "@babel/plugin-transform-regenerator@^7.8.7": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" @@ -799,6 +868,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.10.5", "@babel/types@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" + integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@csstools/convert-colors@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" @@ -4969,7 +5047,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5, lodash@~4.17.10: +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.5, lodash@~4.17.10: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== @@ -5374,6 +5452,23 @@ mixin-deep@^1.2.0: dependencies: minimist "^1.2.5" +mobx-react-lite@>=2.0.6: + version "2.0.7" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.0.7.tgz#1bfb3b4272668e288047cf0c7940b14e91cba284" + integrity sha512-YKAh2gThC6WooPnVZCoC+rV1bODAKFwkhxikzgH18wpBjkgTkkR9Sb0IesQAH5QrAEH/JQVmy47jcpQkf2Au3Q== + +mobx-react@^6.2.5: + version "6.2.5" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.2.5.tgz#9020a17b79cc6dc3d124ad89ab36eb9ea540a45b" + integrity sha512-LxtXXW0GkOAO6VOIg2m/6WL6ZuKlzOWwESIFdrWelI0ZMIvtKCMZVUuulcO5GAWSDsH0ApaMkGLoaPqKjzyziQ== + dependencies: + mobx-react-lite ">=2.0.6" + +mobx@^5.15.4: + version "5.15.4" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.4.tgz#9da1a84e97ba624622f4e55a0bf3300fb931c2ab" + integrity sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -6851,6 +6946,11 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.1 source-map "^0.6.1" supports-color "^6.1.0" +preact@^10.4.6: + version "10.4.6" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.4.6.tgz#86cc43396e4bdd755726a2b4b1f0529e78067cd3" + integrity sha512-80WJfXH53yyINig5Wza/8MD9n4lMg9G6aN00ws0ptsAaY/Fu/M7xW4zICf7OLfocVltxS30wvNQ8oIbUyZS1tw== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"