,\r\n 80\r\n );\r\n\r\n return items;\r\n }\r\n}\r\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/avatar'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/username'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/humanTime'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/utils/string'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['forum/components/UserCard'];","import app from 'flarum/forum/app';\r\nimport Component from 'flarum/common/Component';\r\nimport avatar from 'flarum/common/helpers/avatar';\r\nimport username from 'flarum/common/helpers/username';\r\nimport humanTime from 'flarum/common/helpers/humanTime';\r\nimport { truncate } from 'flarum/common/utils/string';\r\nimport Link from 'flarum/common/components/Link';\r\nimport UserCard from 'flarum/forum/components/UserCard';\r\nimport type Discussion from 'flarum/common/models/Discussion';\r\nimport ItemList from 'flarum/common/utils/ItemList';\r\nimport extractText from 'flarum/common/utils/extractText';\r\nimport type Mithril from 'mithril';\r\n\r\ninterface Attrs {\r\n discussion: Discussion;\r\n}\r\n\r\nexport default class LastDiscussionWidget extends Component {\r\n /**\r\n * Whether or not the user hover card is visible.\r\n */\r\n cardVisible!: boolean;\r\n\r\n oninit(vnode) {\r\n super.oninit(vnode);\r\n\r\n this.cardVisible = false;\r\n }\r\n\r\n view() {\r\n const discussion = this.attrs.discussion;\r\n\r\n if (!discussion) {\r\n return
, 10);\r\n\r\n return items;\r\n }\r\n\r\n oncreate(vnode) {\r\n super.oncreate(vnode);\r\n\r\n let timeout: number;\r\n\r\n this.$()\r\n .on('mouseover', '.LastDiscussion-avatar, .LastDiscussion-usernameLinkUserCard, .username, .UserCard', () => {\r\n clearTimeout(timeout);\r\n timeout = window.setTimeout(this.showCard.bind(this), 300);\r\n })\r\n .on('mouseout', '.LastDiscussion-avatar, .LastDiscussion-usernameLinkUserCard, .username, .UserCard', () => {\r\n clearTimeout(timeout);\r\n timeout = window.setTimeout(this.hideCard.bind(this), 150);\r\n });\r\n }\r\n\r\n onremove(vnode): void {\r\n super.onremove(vnode);\r\n\r\n this.$().off('mouseover mouseout');\r\n }\r\n\r\n /**\r\n * Show the user card.\r\n */\r\n showCard() {\r\n this.cardVisible = true;\r\n\r\n m.redraw();\r\n\r\n setTimeout(() => this.$('.UserCard').addClass('in'));\r\n }\r\n\r\n /**\r\n * Hide the user card.\r\n */\r\n hideCard() {\r\n $('.UserCard').removeClass('in');\r\n this.cardVisible = false;\r\n m.redraw();\r\n }\r\n}\r\n","import Component from 'flarum/common/Component';\r\nimport Link from 'flarum/common/components/Link';\r\n\r\nimport icon from 'flarum/common/helpers/icon';\r\nimport ItemList from 'flarum/common/utils/ItemList';\r\nimport sortTags from 'flarum/tags/utils/sortTags';\r\n\r\nimport StatWidget from './StatWidget';\r\nimport LastDiscussionWidget from './LastDiscussionWidget';\r\nimport app from 'flarum/forum/app';\r\nimport classList from 'flarum/common/utils/classList';\r\n\r\nimport type Mithril from 'mithril';\r\n\r\ninterface Attrs {\r\n model: any;\r\n parent: any;\r\n}\r\n\r\n/*\r\n * Provide compatibility for Flarum Tag Passwords extension, this is to ensure that locked tag with Password or Group permission has view restriction on latest discussion.\r\n * To know if a tag is protected, there is an isUnlocked variable that is specific for this extension.\r\n * https://github.com/datlechin/flarum-tag-passwords\r\n * \r\n */\r\ninterface TagLocked {\r\n icon: icon;\r\n text: string;\r\n isVisible: boolean;\r\n}\r\n\r\nexport default class Category extends Component {\r\n tag!: any;\r\n isChild!: boolean;\r\n collapsed!: boolean;\r\n compactMobileMode!: boolean;\r\n tagLocked!: TagLocked;\r\n\r\n oninit(vnode) {\r\n super.oninit(vnode);\r\n\r\n this.tag = this.attrs.model;\r\n\r\n this.isChild = this.attrs.parent != null && this.attrs.parent != undefined;\r\n\r\n this.collapsed = false;\r\n\r\n // Identify if the tag has been Goup or Password protected with flarum-tag-passwords extension.\r\n if (typeof this.tag.isUnlocked == 'function') {\r\n if ((this.tag.isGroupProtected() || this.tag.isPasswordProtected()) && !this.tag.isUnlocked()) {\r\n this.tagLocked = {\r\n icon: this.tag.isPasswordProtected() ? icon('fas fa-lock') : icon('fas fa-user-lock'),\r\n text: this.tag.isPasswordProtected() ? app.translator.trans('datlechin-tag-passwords.forum.tags_page.password_protected') : app.translator.trans('datlechin-tag-passwords.forum.tags_page.group_protected'),\r\n isVisible: this.tag.isProtectedTagDisplayedForTagsPage() == true\r\n };\r\n }\r\n }\r\n\r\n window.addEventListener('resize', function () {\r\n m.redraw();\r\n });\r\n }\r\n\r\n view() {\r\n const tag = this.tag;\r\n\r\n if (!tag) {\r\n return null;\r\n } else if (this.tagLocked && !this.tagLocked.isVisible) {\r\n // Hide the navigation when protected Tag in 'Tag Passwords > Display protected Tag in Tags page navigation' is disabled\r\n return null;\r\n }\r\n\r\n this.compactMobileMode = !!app.forum.attribute('categories.compactMobile');\r\n\r\n return (\r\n
\r\n {this.categoryItems().toArray()}\r\n
\r\n );\r\n }\r\n\r\n categoryItems() {\r\n const items = new ItemList();\r\n const tag = this.tag;\r\n\r\n const children = this.isChild ? [] : sortTags(tag.children() || []);\r\n\r\n items.add(\r\n 'link',\r\n \r\n {this.contentItems().toArray()}\r\n ,\r\n 100\r\n );\r\n\r\n if (!this.compactMobileMode && !this.isChild) {\r\n items.add(\r\n 'children',\r\n {children.map((child) => [Category.component({ model: child, parent: this })])},\r\n 10\r\n );\r\n }\r\n\r\n return items;\r\n }\r\n\r\n contentItems() {\r\n const items = new ItemList();\r\n\r\n const tag = this.tag;\r\n const children = this.isChild ? [] : sortTags(tag.children() || []);\r\n\r\n items.add('alignStart',
,\n 80\n );\n\n return items;\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/avatar'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/username'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/humanTime'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/utils/string'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['forum/components/UserCard'];","import app from 'flarum/forum/app';\nimport Component from 'flarum/common/Component';\nimport avatar from 'flarum/common/helpers/avatar';\nimport username from 'flarum/common/helpers/username';\nimport humanTime from 'flarum/common/helpers/humanTime';\nimport { truncate } from 'flarum/common/utils/string';\nimport Link from 'flarum/common/components/Link';\nimport UserCard from 'flarum/forum/components/UserCard';\nimport type Discussion from 'flarum/common/models/Discussion';\nimport ItemList from 'flarum/common/utils/ItemList';\nimport extractText from 'flarum/common/utils/extractText';\nimport type Mithril from 'mithril';\n\ninterface Attrs {\n discussion: Discussion;\n}\n\nexport default class LastDiscussionWidget extends Component {\n /**\n * Whether or not the user hover card is visible.\n */\n cardVisible!: boolean;\n\n oninit(vnode) {\n super.oninit(vnode);\n\n this.cardVisible = false;\n }\n\n view() {\n const discussion = this.attrs.discussion;\n\n if (!discussion) {\n return
, 10);\n\n return items;\n }\n\n oncreate(vnode) {\n super.oncreate(vnode);\n\n let timeout: number;\n\n this.$()\n .on('mouseover', '.LastDiscussion-avatar, .LastDiscussion-usernameLinkUserCard, .username, .UserCard', () => {\n clearTimeout(timeout);\n timeout = window.setTimeout(this.showCard.bind(this), 300);\n })\n .on('mouseout', '.LastDiscussion-avatar, .LastDiscussion-usernameLinkUserCard, .username, .UserCard', () => {\n clearTimeout(timeout);\n timeout = window.setTimeout(this.hideCard.bind(this), 150);\n });\n }\n\n onremove(vnode): void {\n super.onremove(vnode);\n\n this.$().off('mouseover mouseout');\n }\n\n /**\n * Show the user card.\n */\n showCard() {\n this.cardVisible = true;\n\n m.redraw();\n\n setTimeout(() => this.$('.UserCard').addClass('in'));\n }\n\n /**\n * Hide the user card.\n */\n hideCard() {\n $('.UserCard').removeClass('in');\n this.cardVisible = false;\n m.redraw();\n }\n}\n","import Component from 'flarum/common/Component';\nimport Link from 'flarum/common/components/Link';\n\nimport icon from 'flarum/common/helpers/icon';\nimport ItemList from 'flarum/common/utils/ItemList';\nimport sortTags from 'flarum/tags/utils/sortTags';\n\nimport StatWidget from './StatWidget';\nimport LastDiscussionWidget from './LastDiscussionWidget';\nimport app from 'flarum/forum/app';\nimport classList from 'flarum/common/utils/classList';\n\nimport type Mithril from 'mithril';\n\ninterface Attrs {\n model: any;\n parent: any;\n}\n\n/*\n * Provide compatibility for Flarum Tag Passwords extension, this is to ensure that locked tag with Password or Group permission has view restriction on latest discussion.\n * To know if a tag is protected, there is an isUnlocked variable that is specific for this extension.\n * https://github.com/datlechin/flarum-tag-passwords\n * \n */\ninterface TagLocked {\n icon: icon;\n text: string;\n isVisible: boolean;\n}\n\nexport default class Category extends Component {\n tag!: any;\n isChild!: boolean;\n collapsed!: boolean;\n compactMobileMode!: boolean;\n tagLocked!: TagLocked;\n\n oninit(vnode) {\n super.oninit(vnode);\n\n this.tag = this.attrs.model;\n\n this.isChild = this.attrs.parent != null && this.attrs.parent != undefined;\n\n this.collapsed = false;\n\n // Identify if the tag has been Goup or Password protected with flarum-tag-passwords extension.\n if (typeof this.tag.isUnlocked == 'function') {\n if ((this.tag.isGroupProtected() || this.tag.isPasswordProtected()) && !this.tag.isUnlocked()) {\n this.tagLocked = {\n icon: this.tag.isPasswordProtected() ? icon('fas fa-lock') : icon('fas fa-user-lock'),\n text: this.tag.isPasswordProtected() ? app.translator.trans('datlechin-tag-passwords.forum.tags_page.password_protected') : app.translator.trans('datlechin-tag-passwords.forum.tags_page.group_protected'),\n isVisible: this.tag.isProtectedTagDisplayedForTagsPage() == true\n };\n }\n }\n\n window.addEventListener('resize', function () {\n m.redraw();\n });\n }\n\n view() {\n const tag = this.tag;\n\n if (!tag) {\n return null;\n } else if (this.tagLocked && !this.tagLocked.isVisible) {\n // Hide the navigation when protected Tag in 'Tag Passwords > Display protected Tag in Tags page navigation' is disabled\n return null;\n }\n\n this.compactMobileMode = !!app.forum.attribute('categories.compactMobile');\n\n return (\n
\n {this.categoryItems().toArray()}\n
\n );\n }\n\n categoryItems() {\n const items = new ItemList();\n const tag = this.tag;\n\n const children = this.isChild ? [] : sortTags(tag.children() || []);\n\n items.add(\n 'link',\n \n {this.contentItems().toArray()}\n ,\n 100\n );\n\n if (!this.compactMobileMode && !this.isChild) {\n items.add(\n 'children',\n {children.map((child) => [Category.component({ model: child, parent: this })])},\n 10\n );\n }\n\n return items;\n }\n\n contentItems() {\n const items = new ItemList();\n\n const tag = this.tag;\n const children = this.isChild ? [] : sortTags(tag.children() || []);\n\n items.add('alignStart',
,\n 50\n );\n\n return items;\n }\n\n oncreate(vnode) {\n super.oncreate(vnode);\n\n app.setTitle(extractText(app.translator.trans('askvortsov-categories.forum.all_categories.meta_title_text')));\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['tags/forum/components/TagsPage'];","import { extend } from 'flarum/common/extend';\nimport IndexPage from 'flarum/forum/components/IndexPage';\nimport LinkButton from 'flarum/common/components/LinkButton';\nimport Model from 'flarum/common/Model';\nimport Tag from 'flarum/tags/models/Tag';\nimport CategoriesPage from './components/CategoriesPage';\nimport TagsPage from 'flarum/tags/forum/components/TagsPage';\nimport Category from './components/Category';\nimport LastDiscussionWidget from './components/LastDiscussionWidget';\nimport StatWidget from './components/StatWidget';\n\nfunction pruneIndexNav(items, func) {\n const isTagsPageVisible = app.forum.attribute('categories.keepTagsNav');\n\n const isCustomTagsHidden = (app.current.matches(CategoriesPage) || app.current.matches(TagsPage));\n for (const item in items.items) {\n if (func(item)) {\n if(item == 'tags') {\n /*\n * Tags must be visible on the navibation bar, when the User has selected to keep Tags within the Extension Settings.\n * Finding all items that begins with 'tag' will also load 'tags', due to custom tag are labelled 'tag1', 'tag2' and so-on\n */\n if (!isTagsPageVisible) {\n items.remove(item);\n }\n } else {\n /*\n * This is for custom tags, where they should not be visible within CategoriesPage and TagsPage\n */\n if (isCustomTagsHidden) {\n items.remove(item);\n }\n }\n }\n }\n}\n\napp.initializers.add('askvortsov/flarum-categories', () => {\n app.routes.categories = {\n path: '/categories',\n component: CategoriesPage,\n };\n\n Tag.prototype.postCount = Model.attribute('postCount');\n\n extend(IndexPage.prototype, 'navItems', function (items) {\n items.add(\n 'categories',\n \n {app.translator.trans('askvortsov-categories.forum.index.categories_link')}\n ,\n -9.5\n );\n\n if (items.has('moreTags')) {\n items.replace('moreTags', {app.translator.trans('flarum-tags.forum.index.more_link')});\n }\n\n pruneIndexNav(items, (item) => item.startsWith('tag'));\n\n return items;\n });\n\n extend(IndexPage.prototype, 'sidebarItems', function (items) {\n pruneIndexNav(items, (item) => item !== 'newDiscussion' && item !== 'nav');\n return items;\n });\n});\n\nexport default {\n 'components/CategoriesPage': CategoriesPage,\n 'components/Category': Category,\n 'components/LastDiscussionWidget': LastDiscussionWidget,\n 'components/StatWidget': StatWidget,\n};\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","flarum","core","compat","_setPrototypeOf","p","setPrototypeOf","bind","__proto__","_inheritsLoose","subClass","superClass","create","constructor","StatWidget","_Component","apply","arguments","_proto","view","m","class","classList","app","this","content","toArray","items","ItemList","add","attrs","count","className","icon","label","Component","LastDiscussionWidget","_this","_len","length","args","Array","_key","concat","cardVisible","oninit","vnode","_discussion$lastPostN","discussion","lastPostedUser","Link","href","lastPostNumber","user","extractText","username","avatar","humanTime","lastPostedAt","style","display","margin","role","truncate","title","card","UserCard","controlsButtonClassName","oncreate","timeout","_this2","$","on","clearTimeout","window","setTimeout","showCard","hideCard","onremove","off","_this3","redraw","addClass","removeClass","Category","tag","isChild","collapsed","compactMobileMode","tagLocked","model","parent","undefined","isUnlocked","isGroupProtected","isPasswordProtected","text","isVisible","isProtectedTagDisplayedForTagsPage","addEventListener","slug","SubCategory","ParentCategory","compactMobile","categoryItems","children","sortTags","backgroundColor","color","contentItems","map","child","component","alignStartItems","alignEndItems","_this4","iconItems","mainItems","onclick","e","toggleArrow","lockedItems","statItems","empty","lastPostedDiscussion","lastDiscussionItems","classes","iconClasses","name","description","Intl","NumberFormat","format","discussionCount","postCount","hasClass","closest","preventDefault","stopPropagation","CategoriesPage","_Page","tags","loading","preloaded","filter","then","LoadingIndicator","pageItems","IndexPage","containerItems","pinned","position","cloud","listItems","tagLabel","link","Page","pruneIndexNav","func","isTagsPageVisible","forum","attribute","isCustomTagsHidden","current","matches","TagsPage","item","remove","initializers","routes","categories","path","Tag","Model","extend","LinkButton","route","translator","trans","has","replace","startsWith"],"sourceRoot":""}
\ No newline at end of file