├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── extend.php
├── js
├── admin.js
├── dist
│ ├── admin.js
│ ├── admin.js.map
│ ├── forum.js
│ └── forum.js.map
├── forum.js
├── package-lock.json
├── package.json
├── src
│ ├── admin
│ │ ├── components
│ │ │ └── LevelRanksSettingsModal.js
│ │ └── index.js
│ └── forum
│ │ ├── components
│ │ └── LevelBar.js
│ │ └── index.js
└── webpack.config.js
├── resources
├── less
│ └── forum.less
└── locale
│ ├── en.yml
│ └── pl.yml
└── src
└── Listeners
└── LoadSettingsFromDatabase.php
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | .DS_Store
61 |
62 | # flarum webpack
63 | v8-compile-cache-0
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Shahiem Seymor
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Level ranks by ReFlar
3 |
4 | [](https://github.com/ReFlar/level-ranks/blob/master/LICENSE) [](https://github.com/ReFlar/level-ranks)
5 |
6 | Add a level/expierence bar to your flarum Forum.
7 |
8 | ### Installation :balloon:
9 |
10 | Install it with composer:
11 |
12 | ```sh
13 | composer require reflar/level-ranks
14 | ```
15 |
16 | ### Issues 🐛
17 |
18 | [Open an issue on Github](https://github.com/ReFlar/level-ranks/issues)
19 |
20 | Suggestions? Please feel free to give me some suggestions
21 |
22 | ### Links 🔗
23 |
24 | - [Github](https://github.com/ReFlar/level-ranks)
25 | - [Packagist](https://packagist.org/packages/reflar/level-ranks)
26 | - [Buy me a house with $1 💰](https://paypal.me/shahiemseymor)
27 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "reflar/level-ranks",
3 | "description": "Add a level/experience bar to your flarum Forum.",
4 | "keywords": [
5 | "extension",
6 | "flarum",
7 | "experience",
8 | "level",
9 | "xp"
10 | ],
11 | "type": "flarum-extension",
12 | "authors": [
13 | {
14 | "name": "Shahiem Seymor",
15 | "email": "s.seymor@live.nl",
16 | "homepage": "http://shahiemseymor.com/"
17 | }
18 | ],
19 | "support": {
20 | "issues": "https://github.com/ReFlar/level-ranks/issues",
21 | "source": "https://github.com/ReFlar/level-ranks"
22 | },
23 | "require": {
24 | "flarum/core": "^0.1.0-beta.8"
25 | },
26 | "extra": {
27 | "flarum-extension": {
28 | "title": "ReFlar Level Ranks",
29 | "icon": {
30 | "name": "fas fa-percent",
31 | "backgroundColor": "#263238",
32 | "color": "#fff"
33 | }
34 | }
35 | },
36 | "autoload": {
37 | "psr-4": {
38 | "Reflar\\LevelRanks\\": "src/"
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/extend.php:
--------------------------------------------------------------------------------
1 | js(__DIR__.'/js/dist/forum.js')
22 | ->css(__DIR__.'/resources/less/forum.less'),
23 | (new Extend\Frontend('admin'))
24 | ->js(__DIR__.'/js/dist/admin.js'),
25 | new Extend\Locales(__DIR__.'/resources/locale'),
26 | function (Dispatcher $events) {
27 | $events->subscribe(Listeners\LoadSettingsFromDatabase::class);
28 | },
29 | ];
30 |
--------------------------------------------------------------------------------
/js/admin.js:
--------------------------------------------------------------------------------
1 | export * from './src/admin';
--------------------------------------------------------------------------------
/js/dist/admin.js:
--------------------------------------------------------------------------------
1 | module.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=7)}([function(e,t){e.exports=flarum.core.compat.app},function(e,t,r){"use strict";function n(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}r.d(t,"a",function(){return n})},,,,function(e,t){e.exports=flarum.core.compat["components/SettingsModal"]},,function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n),a=r(1),l=r(5),u=function(e){function t(){return e.apply(this,arguments)||this}Object(a.a)(t,e);var r=t.prototype;return r.className=function(){return"LevelRanksSettingsModal Modal--medium"},r.title=function(){return app.translator.trans("reflar-level-ranks.admin.settings.title")},r.form=function(){return[m("div",{className:"Form-group"},m("div",{className:"Form-group"},m("label",null,app.translator.trans("reflar-level-ranks.admin.settings.levelText")),m("input",{placeholder:app.translator.trans("reflar-level-ranks.lib.defaults.level"),className:"FormControl",bidi:this.setting("reflar-level-ranks.pointsText")})))]},t}(r.n(l).a);o.a.initializers.add("reflar-level-ranks",function(){o.a.extensionSettings["reflar-level-ranks"]=function(){return o.a.modal.show(new u)}})}]);
2 | //# sourceMappingURL=admin.js.map
--------------------------------------------------------------------------------
/js/dist/admin.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack://@reflar/level-ranks/webpack/bootstrap","webpack://@reflar/level-ranks/external \"flarum.core.compat['app']\"","webpack://@reflar/level-ranks/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@reflar/level-ranks/external \"flarum.core.compat['components/SettingsModal']\"","webpack://@reflar/level-ranks/./src/admin/components/LevelRanksSettingsModal.js","webpack://@reflar/level-ranks/./src/admin/index.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","flarum","core","compat","_inheritsLoose","subClass","superClass","constructor","__proto__","__webpack_exports__","LevelRanksSettingsModal","className","title","app","translator","trans","form","placeholder","bidi","this","setting","SettingsModal","initializers","add","extensionSettings","modal","show"],"mappings":"2BACA,IAAAA,EAAA,GAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,GAAA,CACAG,EAAAH,EACAI,GAAA,EACAH,QAAA,IAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QA0DA,OArDAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,EAAA,CAA0CK,YAAA,EAAAC,IAAAL,KAK1CZ,EAAAkB,EAAA,SAAAhB,GACA,oBAAAiB,eAAAC,aACAN,OAAAC,eAAAb,EAAAiB,OAAAC,YAAA,CAAwDC,MAAA,WAExDP,OAAAC,eAAAb,EAAA,cAAiDmB,OAAA,KAQjDrB,EAAAsB,EAAA,SAAAD,EAAAE,GAEA,GADA,EAAAA,IAAAF,EAAArB,EAAAqB,IACA,EAAAE,EAAA,OAAAF,EACA,KAAAE,GAAA,iBAAAF,QAAAG,WAAA,OAAAH,EACA,IAAAI,EAAAX,OAAAY,OAAA,MAGA,GAFA1B,EAAAkB,EAAAO,GACAX,OAAAC,eAAAU,EAAA,WAAyCT,YAAA,EAAAK,UACzC,EAAAE,GAAA,iBAAAF,EAAA,QAAAM,KAAAN,EAAArB,EAAAU,EAAAe,EAAAE,EAAA,SAAAA,GAAgH,OAAAN,EAAAM,IAAqBC,KAAA,KAAAD,IACrI,OAAAF,GAIAzB,EAAA6B,EAAA,SAAA1B,GACA,IAAAS,EAAAT,KAAAqB,WACA,WAA2B,OAAArB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAiB,EAAAC,GAAsD,OAAAjB,OAAAkB,UAAAC,eAAA1B,KAAAuB,EAAAC,IAGtD/B,EAAAkC,EAAA,GAIAlC,IAAAmC,EAAA,mBClFAhC,EAAAD,QAAAkC,OAAAC,KAAAC,OAAA,kCCAe,SAAAC,EAAAC,EAAAC,GACfD,EAAAR,UAAAlB,OAAAY,OAAAe,EAAAT,WACAQ,EAAAR,UAAAU,YAAAF,EACAA,EAAAG,UAAAF,EAHAzC,EAAAU,EAAAkC,EAAA,sBAAAL,sBCAApC,EAAAD,QAAAkC,OAAAC,KAAAC,OAAA,oGCEqBO,4GACjBC,qBACI,MAAO,2CAGXC,iBACI,OAAOC,IAAIC,WAAWC,MAAM,8CAGhCC,gBACI,MAAO,CACH3C,EAAA,OAAKsC,UAAU,cACXtC,EAAA,OAAKsC,UAAU,cACXtC,EAAA,aAAQwC,IAAIC,WAAWC,MAAM,gDAC7B1C,EAAA,SAAO4C,YAAaJ,IAAIC,WAAWC,MAAM,yCAA0CJ,UAAU,cAAcO,KAAMC,KAAKC,QAAQ,iDAd7FC,GCCrDR,IAAIS,aAAaC,IAAI,qBAAsB,WACvCV,IAAIW,kBAAkB,sBAAwB,kBAAMX,IAAIY,MAAMC,KAAK,IAAIhB","file":"admin.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 7);\n","module.exports = flarum.core.compat['app'];","export default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n}","module.exports = flarum.core.compat['components/SettingsModal'];","import SettingsModal from 'flarum/components/SettingsModal';\r\n\r\nexport default class LevelRanksSettingsModal extends SettingsModal {\r\n className() {\r\n return 'LevelRanksSettingsModal Modal--medium';\r\n }\r\n\r\n title() {\r\n return app.translator.trans('reflar-level-ranks.admin.settings.title');\r\n }\r\n\r\n form() {\r\n return [\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n ];\r\n }\r\n}","import app from 'flarum/app';\r\nimport LevelRanksSettingsModal from './components/LevelRanksSettingsModal';\r\n\r\napp.initializers.add('reflar-level-ranks', () => {\r\n app.extensionSettings['reflar-level-ranks'] = () => app.modal.show(new LevelRanksSettingsModal());\r\n});"],"sourceRoot":""}
--------------------------------------------------------------------------------
/js/dist/forum.js:
--------------------------------------------------------------------------------
1 | module.exports=function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=6)}([function(t,e){t.exports=flarum.core.compat.app},function(t,e,r){"use strict";function n(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,t.__proto__=e}r.d(e,"a",function(){return n})},function(t,e){t.exports=flarum.core.compat.extend},function(t,e){t.exports=flarum.core.compat["components/PostUser"]},function(t,e){t.exports=flarum.core.compat.Component},,function(t,e,r){"use strict";r.r(e);var n=r(0),o=r.n(n),s=r(2),a=r(3),u=r.n(a),i=r(1),c=r(4),l=function(t){function e(){return t.apply(this,arguments)||this}Object(i.a)(e,t);var r=e.prototype;return r.config=function(){this.$().tooltip({container:"body"})},r.view=function(){var t=this.props.user,e=o.a.forum.attribute("reflar-level-ranks.pointsText")||o.a.translator.trans("reflar-level-ranks.lib.defaults.level"),r=21*(t.commentCount()-t.discussionCount())+33*t.discussionCount(),n=Math.floor(r/135),s=100/135*(r-135*n);return m("div",{class:"PostUser-level",title:r+" "+o.a.translator.trans("reflar-level-ranks.forum.desc.expText")},m("span",{class:"PostUser-text"},m("span",{class:"PostUser-levelText"},e)," ",m("span",{class:"PostUser-levelPoints"},n)),m("div",{class:"PostUser-bar PostUser-bar--empty"}),m("div",{class:"PostUser-bar",style:"width: "+s+"%;"}))},e}(r.n(c).a);o.a.initializers.add("reflar-level-ranks",function(t){Object(s.extend)(u.a.prototype,"view",function(t){var e=this.props.post.user();e&&t.children.push(l.component({user:e}))})})}]);
2 | //# sourceMappingURL=forum.js.map
--------------------------------------------------------------------------------
/js/dist/forum.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack://@reflar/level-ranks/webpack/bootstrap","webpack://@reflar/level-ranks/external \"flarum.core.compat['app']\"","webpack://@reflar/level-ranks/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@reflar/level-ranks/external \"flarum.core.compat['extend']\"","webpack://@reflar/level-ranks/external \"flarum.core.compat['components/PostUser']\"","webpack://@reflar/level-ranks/external \"flarum.core.compat['Component']\"","webpack://@reflar/level-ranks/./src/forum/components/LevelBar.js","webpack://@reflar/level-ranks/./src/forum/index.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","flarum","core","compat","_inheritsLoose","subClass","superClass","constructor","__proto__","__webpack_exports__","LevelBar","config","this","$","tooltip","container","view","user","props","pointsText","app","forum","attribute","translator","trans","expTotal","commentCount","discussionCount","expLevel","Math","floor","expPercent","class","title","style","Component","initializers","add","extend","PostUser","post","children","push","component"],"mappings":"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","file":"forum.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 6);\n","module.exports = flarum.core.compat['app'];","export default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n subClass.__proto__ = superClass;\n}","module.exports = flarum.core.compat['extend'];","module.exports = flarum.core.compat['components/PostUser'];","module.exports = flarum.core.compat['Component'];","import Component from 'flarum/Component';\nimport app from 'flarum/app';\n\nexport default class LevelBar extends Component {\n config() {\n this.$().tooltip({ container: 'body' });\n }\n\n view() {\n const user = this.props.user;\n const pointsText = app.forum.attribute('reflar-level-ranks.pointsText') || app.translator.trans('reflar-level-ranks.lib.defaults.level');\n\n let expComments = (user.commentCount() - user.discussionCount()) * 21,\n expDiscussions = user.discussionCount() * 33;\n\n let expTotal = expComments + expDiscussions,\n expLevel = Math.floor(expTotal / 135),\n expPercent = (100 / 135) * ((expTotal) - (expLevel * 135));\n\n return (\n \n
\n {pointsText}\n \n {expLevel}\n \n
\n
\n
\n );\n }\n}\n","import app from 'flarum/app';\nimport { extend } from 'flarum/extend';\nimport PostUser from 'flarum/components/PostUser';\nimport LevelBar from './components/LevelBar';\n\napp.initializers.add('reflar-level-ranks', app => {\n\textend(PostUser.prototype, 'view', function (view) {\n const user = this.props.post.user();\n\n if (!user) return;\n\n\t\tview.children.push(LevelBar.component({ user }))\n\t});\n});\n"],"sourceRoot":""}
--------------------------------------------------------------------------------
/js/forum.js:
--------------------------------------------------------------------------------
1 | export * from './src/forum';
--------------------------------------------------------------------------------
/js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@reflar/level-ranks",
3 | "version": "0.0.0",
4 | "dependencies": {
5 | "flarum-webpack-config": "^0.1.0-beta.8",
6 | "webpack": "^4.0.0",
7 | "webpack-cli": "^3.0.7"
8 | },
9 | "scripts": {
10 | "build": "webpack --mode production",
11 | "watch": "webpack --mode development --watch"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/js/src/admin/components/LevelRanksSettingsModal.js:
--------------------------------------------------------------------------------
1 | import SettingsModal from 'flarum/components/SettingsModal';
2 |
3 | export default class LevelRanksSettingsModal extends SettingsModal {
4 | className() {
5 | return 'LevelRanksSettingsModal Modal--medium';
6 | }
7 |
8 | title() {
9 | return app.translator.trans('reflar-level-ranks.admin.settings.title');
10 | }
11 |
12 | form() {
13 | return [
14 |
15 |
16 |
17 |
18 |
19 |
20 | ];
21 | }
22 | }
--------------------------------------------------------------------------------
/js/src/admin/index.js:
--------------------------------------------------------------------------------
1 | import app from 'flarum/app';
2 | import LevelRanksSettingsModal from './components/LevelRanksSettingsModal';
3 |
4 | app.initializers.add('reflar-level-ranks', () => {
5 | app.extensionSettings['reflar-level-ranks'] = () => app.modal.show(new LevelRanksSettingsModal());
6 | });
--------------------------------------------------------------------------------
/js/src/forum/components/LevelBar.js:
--------------------------------------------------------------------------------
1 | import Component from 'flarum/Component';
2 | import app from 'flarum/app';
3 |
4 | export default class LevelBar extends Component {
5 | config() {
6 | this.$().tooltip({ container: 'body' });
7 | }
8 |
9 | view() {
10 | const user = this.props.user;
11 | const pointsText = app.forum.attribute('reflar-level-ranks.pointsText') || app.translator.trans('reflar-level-ranks.lib.defaults.level');
12 |
13 | let expComments = (user.commentCount() - user.discussionCount()) * 21,
14 | expDiscussions = user.discussionCount() * 33;
15 |
16 | let expTotal = expComments + expDiscussions,
17 | expLevel = Math.floor(expTotal / 135),
18 | expPercent = (100 / 135) * ((expTotal) - (expLevel * 135));
19 |
20 | return (
21 |
22 |
23 | {pointsText}
24 |
25 | {expLevel}
26 |
27 |
28 |
29 |
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/js/src/forum/index.js:
--------------------------------------------------------------------------------
1 | import app from 'flarum/app';
2 | import { extend } from 'flarum/extend';
3 | import PostUser from 'flarum/components/PostUser';
4 | import LevelBar from './components/LevelBar';
5 |
6 | app.initializers.add('reflar-level-ranks', app => {
7 | extend(PostUser.prototype, 'view', function (view) {
8 | const user = this.props.post.user();
9 |
10 | if (!user) return;
11 |
12 | view.children.push(LevelBar.component({ user }))
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/js/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('flarum-webpack-config');
2 |
3 | module.exports = config();
--------------------------------------------------------------------------------
/resources/less/forum.less:
--------------------------------------------------------------------------------
1 | .PostUser-level {
2 | float: left;
3 | position: relative;
4 | margin-left: -80px;
5 | margin-top: 75px;
6 | width: 64px;
7 | text-align: center;
8 | }
9 |
10 | div.PostUser-bar--empty {
11 | background: @control-bg;
12 | }
13 |
14 | .PostUser-bar {
15 | background: @primary-color;
16 | border-radius: 10px;
17 | width: 100%;
18 | height: 10px;
19 | position: absolute;
20 | top: 25px;
21 | }
22 |
23 | .PostUser-levelNumber {
24 | position: relative;
25 | }
26 |
27 | .Post--hidden .PostUser-level {
28 | display: none;
29 | }
30 |
31 | .Post--hidden.revealContent .PostUser-level {
32 | display: block;
33 | }
34 |
--------------------------------------------------------------------------------
/resources/locale/en.yml:
--------------------------------------------------------------------------------
1 | reflar-level-ranks:
2 | admin:
3 | settings:
4 | title: Level Ranks Settings
5 | levelText: Enter the text to be displayed for the points (e.g. Rank, Level)
6 | forum:
7 | desc:
8 | expText: EXP
9 | lib:
10 | defaults:
11 | level: Level
--------------------------------------------------------------------------------
/resources/locale/pl.yml:
--------------------------------------------------------------------------------
1 | reflar-level-ranks:
2 | admin:
3 | settings:
4 | title: Ustawienia Rangi
5 | levelText: Wprowadź tekst, który będzie wyświetlany dla punktów (np. Ranga, Poziom)
6 | forum:
7 | desc:
8 | expText: EXP
9 | lib:
10 | defaults:
11 | level: ranga
12 |
--------------------------------------------------------------------------------
/src/Listeners/LoadSettingsFromDatabase.php:
--------------------------------------------------------------------------------
1 | settings = $settings;
36 | }
37 |
38 | /**
39 | * @param Dispatcher $events
40 | */
41 | public function subscribe(Dispatcher $events)
42 | {
43 | $events->listen(Serializing::class, [$this, 'prepareApiAttributes']);
44 | }
45 |
46 | /**
47 | * @param Serializing $event
48 | */
49 | public function prepareApiAttributes(Serializing $event)
50 | {
51 | if ($event->isSerializer(ForumSerializer::class)) {
52 | $key = 'reflar-level-ranks.pointsText';
53 | $event->attributes[$key] = $this->settings->get($key);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------