├── js ├── .gitignore ├── webpack.config.js ├── src │ ├── admin │ │ ├── index.js │ │ └── components │ │ │ ├── SwitchTagList.js │ │ │ └── Settings.js │ └── forum │ │ ├── utils │ │ ├── craftBadges.js │ │ └── craftTags.js │ │ ├── compat.js │ │ ├── helpers │ │ └── getPostImage.js │ │ ├── components │ │ ├── LastReplies.js │ │ ├── CardItem.js │ │ └── ListItem.js │ │ └── index.js ├── admin.js ├── forum.js ├── package.json └── dist │ ├── admin.js │ ├── forum.js │ ├── admin.js.map │ └── forum.js.map ├── less ├── admin.less └── forum.less ├── .github ├── FUNDING.yml └── dependabot.yml ├── migrations └── 2021_01_31_000000_set_default_settings.php ├── README.md ├── locale ├── en.yml └── ru.yml ├── composer.json ├── LICENSE.md ├── src ├── Api │ └── Controllers │ │ ├── DeleteImageController.php │ │ └── UploadImageController.php └── Extenders │ └── RegisterLessVariables.php └── extend.php /js/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /less/admin.less: -------------------------------------------------------------------------------- 1 | .switchTags{ 2 | display: table; 3 | } 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: "dem13n" 2 | liberapay: "Dem13n" 3 | custom: "https://www.paypal.me/Dem13n" 4 | -------------------------------------------------------------------------------- /js/webpack.config.js: -------------------------------------------------------------------------------- 1 | const config = require('flarum-webpack-config'); 2 | 3 | module.exports = config(); 4 | -------------------------------------------------------------------------------- /js/src/admin/index.js: -------------------------------------------------------------------------------- 1 | import app from 'flarum/app'; 2 | import Settings from './components/Settings'; 3 | 4 | 5 | app.initializers.add('dem13n/discussion/cards', () => { 6 | app.extensionData 7 | .for('dem13n-discussion-cards') 8 | .registerPage(Settings) 9 | }); 10 | 11 | -------------------------------------------------------------------------------- /js/admin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Flarum. 3 | * 4 | * (c) Toby Zerner 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | export * from './src/admin'; 11 | -------------------------------------------------------------------------------- /js/forum.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of Flarum. 3 | * 4 | * (c) Toby Zerner 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | export * from './src/forum'; 11 | -------------------------------------------------------------------------------- /js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "@dem13n/discussion/cards", 4 | "dependencies": { 5 | "flarum-webpack-config": "1.0.0", 6 | "webpack": "^4.43.0", 7 | "webpack-cli": "^3.3.11" 8 | }, 9 | "scripts": { 10 | "dev": "webpack --mode development --watch", 11 | "build": "webpack --mode production" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /js/src/forum/utils/craftBadges.js: -------------------------------------------------------------------------------- 1 | import icon from 'flarum/common/helpers/icon'; 2 | 3 | export default function craftBadges(badges) { 4 | if (badges.length) { 5 | return [m('.cardBadges', [badges.map((badge) => { 6 | return [m('span.cardBadge.Badge.Badge--' + badge.attrs.type, { 7 | 'data-original-title': badge.attrs.label[0], 8 | oncreate: (vnode) => $(vnode.dom).tooltip({placement: 'right'}) 9 | }, [icon(badge.attrs.icon)])] 10 | })])]; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /js/src/forum/utils/craftTags.js: -------------------------------------------------------------------------------- 1 | import Link from 'flarum/common/components/Link'; 2 | import sortTags from 'flarum/tags/utils/sortTags'; 3 | 4 | export default function craftTags(tags) { 5 | if (tags) { 6 | return [sortTags(tags).map(function (tag) { 7 | return [ 8 | 11 | {tag.name()} 12 | 13 | ] 14 | })]; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /migrations/2021_01_31_000000_set_default_settings.php: -------------------------------------------------------------------------------- 1 | 0, 7 | 'cardBadges' => 0, 8 | 'cardFooter' => 0, 9 | 'Views' => 0, 10 | 'markCards' => 0, 11 | 'Replies' => 0, 12 | 'onIndexPage' => 0, 13 | 'smallCards' => 10, 14 | 'desktopCardWidth' => 49, 15 | 'tabletCardWidth' => 49, 16 | 'allowedTags' => [] 17 | ]; 18 | 19 | return Migration::addSettings([ 20 | 'dem13n_discussion_cards' => json_encode($settings), 21 | 'dem13n_discussion_cards_default_image_path' => null 22 | ]); 23 | -------------------------------------------------------------------------------- /js/src/forum/compat.js: -------------------------------------------------------------------------------- 1 | import CardItem from './components/CardItem'; 2 | import ListItem from './components/ListItem'; 3 | import LastReplies from './components/LastReplies'; 4 | import craftTags from "./utils/craftTags"; 5 | import craftBadges from "./utils/craftBadges"; 6 | 7 | export default { 8 | 'dem13n/discussion/cards/components/CardItem': CardItem, 9 | 'dem13n/discussion/cards/components/ListItem': ListItem, 10 | 'dem13n/discussion/cards/components/LastReplies': LastReplies, 11 | 'dem13n/discussion/cards/utils/craftTags': craftTags, 12 | 'dem13n/discussion/cards/utils/craftBadges': craftBadges, 13 | }; 14 | -------------------------------------------------------------------------------- /js/src/forum/helpers/getPostImage.js: -------------------------------------------------------------------------------- 1 | export default function getPostImage(post, key = 1) { 2 | 3 | const regex = //; 4 | const image = app.forum.attribute('dem13nDiscussionCardsDefaultImage'); 5 | const defaultImg = app.forum.attribute("baseUrl") + "/assets/" + image; 6 | 7 | if (post) { 8 | const src = regex.exec(post.contentHtml()); 9 | if (typeof key === "number" && key > 0) { 10 | return (src) ? src[key] : (image ? defaultImg : null); 11 | } else if (key === '~') { 12 | return src; 13 | } else { 14 | return null; 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Discussion Cards 2 | 3 | ![License](https://img.shields.io/badge/license-MIT-blue.svg) 4 | 5 | A [Flarum](http://flarum.org) extension. Allows you to display discussions in the form of cards, the first image of the first post is used as a preview, if there are no images, a stub is displayed 6 | 7 | ![Discussion Cards](https://i.imgur.com/i7FZGHq.png) 8 | 9 | ### Installation 10 | 11 | ```sh 12 | composer require dem13n/discussion-cards 13 | ``` 14 | 15 | ### Updating 16 | 17 | ```sh 18 | composer update dem13n/discussion-cards 19 | php flarum cache:clear 20 | ``` 21 | 22 | ### Links 23 | 24 | - [Packagist](https://packagist.org/packages/dem13n/discussion-cards) 25 | "# Discussion Cards" 26 | -------------------------------------------------------------------------------- /locale/en.yml: -------------------------------------------------------------------------------- 1 | dem13n: 2 | forum: 3 | replies: "Replies: {count}" 4 | admin: 5 | settings: 6 | settings_error: Clear cache, disable that extension, click Uninstall button (on the right), confirm deleting data, then enable extension 7 | default_img: Default image 8 | choose_tags: Choose tags 9 | badges: Show badges 10 | actor_info: Show author 11 | small_cards: Number of primary cards 12 | preview_text: Show short text 13 | show_replies: Show replies 14 | show_views: Show views (when the extension "Flarumite Simple Discussion Views" installed) 15 | output_on_index_page: Output on index page 16 | desktop_card_width: "Width of primary cards on desktop screens: {percent}%" 17 | tablet_card_width: "Width of primary cards on tablets: {percent}%" 18 | mark_cards: Mark cards with unread discussions 19 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dem13n/discussion-cards", 3 | "description": "Output of discussions in form of cards", 4 | "type": "flarum-extension", 5 | "keywords": ["discussion"], 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Dem13n", 10 | "email": "idem13n@gmail.com" 11 | } 12 | ], 13 | "require": { 14 | "flarum/core": "^1.0", 15 | "flarum/tags": "^1.0" 16 | }, 17 | "autoload": { 18 | "psr-4": { 19 | "Dem13n\\Discussion\\Cards\\": "src/" 20 | } 21 | }, 22 | "extra": { 23 | "flarum-extension": { 24 | "title": "Discussion Сards", 25 | "category": "discussion", 26 | "icon": { 27 | "name": "fas fa-border-all", 28 | "backgroundColor": "#2B6205", 29 | "color": "#fff" 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /locale/ru.yml: -------------------------------------------------------------------------------- 1 | dem13n: 2 | forum: 3 | replies: "Ответов: {count}" 4 | admin: 5 | settings: 6 | settings_error: Очистите кэш, отключите расширение, нажмите кнопку удалить (справа), подтвердите удаление данных, затем включите расширение 7 | default_img: Изображение по умолчанию 8 | choose_tags: Выберите разделы 9 | badges: Показывать бейджи 10 | actor_info: Показывать автора 11 | small_cards: Количество основных карточек 12 | preview_text: Показывать краткий текст 13 | show_replies: Показать последних ответивших 14 | show_views: Показывать количество просмотров (при установленном расширении "Flarumite Simple Discussion Views") 15 | output_on_index_page: Выводить на главной странице 16 | desktop_card_width: "Ширина основных карточек в десктопной версии: {percent}%" 17 | tablet_card_width: "Ширина основных карточек на планшетах: {percent}%" 18 | mark_cards: Помечать карточки с непрочитанными дискуссиями 19 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Stichting Flarum (Flarum Foundation) Copyright (c) Dem13n (idem13n@gmail.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /js/src/forum/components/LastReplies.js: -------------------------------------------------------------------------------- 1 | import Component from 'flarum/common/Component'; 2 | import avatar from 'flarum/common/helpers/avatar'; 3 | import icon from 'flarum/common/helpers/icon'; 4 | import Link from 'flarum/common/components/Link'; 5 | 6 | 7 | export default class LastReplies extends Component { 8 | 9 | oninit(vnode) { 10 | super.oninit(vnode); 11 | this.discussion = this.attrs.discussion; 12 | } 13 | 14 | view() { 15 | const discussion = this.discussion; 16 | 17 | // let's assume that the last 10 posts will be enough for us to identify 3 unique users 18 | const posts = discussion.posts().splice(-10); 19 | 20 | const filteredPosts = posts 21 | .filter((post) => { 22 | return !post.isHidden() && post.number() !== 1 && post.contentType() === "comment"; 23 | }) 24 | .sort((a, b) => b.createdAt() - a.createdAt()); 25 | 26 | const groupedUsers = filteredPosts 27 | .map(post => post.user()) 28 | .filter((user, i, self) => { 29 | return self.indexOf(user) === i 30 | }) 31 | .reverse() 32 | // last 3 users 33 | .splice(-3); 34 | 35 | 36 | return groupedUsers.map(user => { 37 | return avatar(user, {className: 'Avatar--mini'}) 38 | }) 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/Api/Controllers/DeleteImageController.php: -------------------------------------------------------------------------------- 1 | settings = $settings; 22 | $this->paths = $paths; 23 | } 24 | 25 | protected function delete(ServerRequestInterface $request) 26 | { 27 | $request->getAttribute('actor')->assertAdmin(); 28 | 29 | $path = $this->settings->get($key = "dem13n_discussion_cards_default_image_path"); 30 | 31 | $this->settings->set($key, null); 32 | 33 | $uploadDir = new Filesystem(new Local($this->paths->public.'/assets')); 34 | 35 | if ($uploadDir->has($path)) { 36 | $uploadDir->delete($path); 37 | } 38 | 39 | return new EmptyResponse(204); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /extend.php: -------------------------------------------------------------------------------- 1 | js(__DIR__ . '/js/dist/forum.js') 13 | ->css(__DIR__ . '/less/forum.less'), 14 | 15 | (new Extend\Frontend('admin')) 16 | ->js(__DIR__ . '/js/dist/admin.js') 17 | ->css(__DIR__ . '/less/admin.less'), 18 | 19 | (new Extend\Locales(__DIR__ . '/locale')), 20 | 21 | (new Extend\ApiController(ListDiscussionsController::class)) 22 | ->addInclude(['firstPost', 'posts', 'posts.user']), 23 | 24 | new Extenders\RegisterLessVariables(), 25 | 26 | (new Extend\Settings()) 27 | ->serializeToForum('dem13nDiscussionCards', 'dem13n_discussion_cards') 28 | ->serializeToForum('dem13nDiscussionCardsDefaultImage', 'dem13n_discussion_cards_default_image_path'), 29 | 30 | (new Extend\Routes('api')) 31 | ->post('/dem13n_discussion_cards_default_image', 'dem13n_discussion_cards_default_image', UploadImageController::class) 32 | ->delete('/dem13n_discussion_cards_default_image', 'dem13n_discussion_cards_default_image.delete', DeleteImageController::class) 33 | ]; 34 | -------------------------------------------------------------------------------- /src/Extenders/RegisterLessVariables.php: -------------------------------------------------------------------------------- 1 | resolving('flarum.assets.forum', function (Assets $assets) { 19 | $assets->css(function (SourceCollector $sources) { 20 | $sources->addString(function () { 21 | $settings = app(SettingsRepositoryInterface::class); 22 | $ext_settings = json_decode($settings->get('dem13n_discussion_cards'), true); 23 | 24 | $vars = [ 25 | 'desktop-card-width' => Arr::get($ext_settings, 'desktopCardWidth', '49') . '%', 26 | 'tablet-card-width' => Arr::get($ext_settings, 'tabletCardWidth', '49') . '%', 27 | ]; 28 | 29 | return array_reduce(array_keys($vars), function ($string, $name) use ($vars) { 30 | return $string . "@$name: {$vars[$name]};"; 31 | }, ''); 32 | 33 | }); 34 | }); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /js/src/admin/components/SwitchTagList.js: -------------------------------------------------------------------------------- 1 | import Component from "flarum/common/Component"; 2 | 3 | import ExtensionPage from 'flarum/admin/components/ExtensionPage'; 4 | import app from 'flarum/app'; 5 | import Stream from 'flarum/common/utils/Stream'; 6 | import Button from 'flarum/common/components/Button'; 7 | import saveSettings from 'flarum/admin/utils/saveSettings'; 8 | import Switch from 'flarum/common/components/Switch'; 9 | import icon from 'flarum/common/helpers/icon'; 10 | import withAttr from 'flarum/common/utils/withAttr'; 11 | import sortTags from 'flarum/tags/utils/sortTags'; 12 | 13 | export default class SwitchTagList extends Component { 14 | 15 | oninit(vnode) { 16 | super.oninit(vnode); 17 | this.tags = this.attrs.tags; 18 | } 19 | 20 | view() { 21 | 22 | return m('.TagGroup', [ 23 | m('ul.TagList', [ 24 | sortTags(app.store.all('tags')).map((tag) => { 25 | const allowedTags = this.tags; 26 | return [ 27 | m(Switch, { 28 | id: tag.slug(), 29 | state: (allowedTags.length) ? allowedTags.includes(tag.slug()) : false, 30 | onchange: function () { 31 | this.state 32 | ? allowedTags.indexOf(this.id) !== -1 && allowedTags.splice(allowedTags.indexOf(this.id), 1) 33 | : allowedTags.push(this.id); 34 | }, 35 | className: 'switchTags' 36 | }, m("li", { 37 | style: { 38 | color: tag.color(), 39 | lineHeight: '20px', 40 | fontSize: '16px', 41 | marginLeft: !(tag.isPrimary() || tag.position() === null) ? '20px' : 0, 42 | } 43 | }, icon(tag.icon()), tag.name()) 44 | ) 45 | ]; 46 | }) 47 | ]) 48 | ]) 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/Api/Controllers/UploadImageController.php: -------------------------------------------------------------------------------- 1 | settings = $settings; 25 | $this->paths = $paths; 26 | } 27 | 28 | public function data(ServerRequestInterface $request, Document $document) 29 | { 30 | $request->getAttribute('actor')->assertAdmin(); 31 | 32 | $file = Arr::get($request->getUploadedFiles(), 'dem13n_discussion_cards_default_image'); 33 | 34 | $tmpFile = tempnam($this->paths->storage . '/tmp', 'card_image'); 35 | $file->moveTo($tmpFile); 36 | 37 | $image = Image::make($tmpFile) 38 | ->resize(400, null, function ($constraint) { 39 | $constraint->aspectRatio(); 40 | $constraint->upsize(); 41 | })->encode('png'); 42 | 43 | file_put_contents($tmpFile, $image); 44 | 45 | $mount = new MountManager([ 46 | 'source' => new Filesystem(new Local(pathinfo($tmpFile, PATHINFO_DIRNAME))), 47 | 'target' => new Filesystem(new Local($this->paths->public . '/assets')), 48 | ]); 49 | 50 | if (($path = $this->settings->get($key = "dem13n_discussion_cards_default_image_path")) && $mount->has($file = "target://$path")) { 51 | $mount->delete($file); 52 | } 53 | 54 | $uploadName = 'card-image-' . Str::lower(Str::random(8)) . '.png'; 55 | 56 | $mount->move('source://' . pathinfo($tmpFile, PATHINFO_BASENAME), "target://$uploadName"); 57 | 58 | $this->settings->set($key, $uploadName); 59 | 60 | return parent::data($request, $document); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /js/src/forum/index.js: -------------------------------------------------------------------------------- 1 | import app from 'flarum/app'; 2 | import {extend, override} from 'flarum/extend'; 3 | import DiscussionList from 'flarum/forum/components/DiscussionList'; 4 | import DiscussionListState from 'flarum/forum/states/DiscussionListState'; 5 | import IndexPage from 'flarum/forum/components/IndexPage'; 6 | import LoadingIndicator from 'flarum/common/components/LoadingIndicator'; 7 | import Placeholder from 'flarum/common/components/Placeholder'; 8 | import Button from 'flarum/common/components/Button'; 9 | import CardItem from './components/CardItem'; 10 | import ListItem from './components/ListItem'; 11 | 12 | app.initializers.add('dem13n/discussion/cards', () => { 13 | 14 | extend(DiscussionListState.prototype, 'requestParams', function (params) { 15 | if (app.current.matches(IndexPage)) { 16 | params.include.push(['firstPost', 'posts', 'posts.user']); 17 | } 18 | }); 19 | 20 | override(DiscussionList.prototype, 'view', function (original) { 21 | const settings = JSON.parse(app.forum.attribute('dem13nDiscussionCards')); 22 | const state = this.attrs.state; 23 | const params = state.getParams(); 24 | let loading; 25 | if (state.isInitialLoading() || state.isLoadingNext()) { 26 | loading = ; 27 | } else if (state.hasNext()) { 28 | loading = Button.component( 29 | { 30 | className: 'Button', 31 | onclick: state.loadNext.bind(state), 32 | }, 33 | app.translator.trans('core.forum.discussion_list.load_more_button') 34 | ); 35 | } 36 | if (state.isEmpty()) { 37 | const text = app.translator.trans('core.forum.discussion_list.empty_text'); 38 | return
{m(Placeholder, {text})}
; 39 | } 40 | if (app.current.matches(IndexPage) && ((settings.allowedTags.length && settings.allowedTags.includes(params.tags)) || (!params.tags && settings.onIndexPage === 1))) { 41 | return ( 42 |
43 |
44 | {state.getPages().map((pg, o) => { 45 | return pg.items.map((discussion, i) => { 46 | return (i < settings.smallCards && o === 0) 47 | ? m(CardItem, {discussion: discussion}) 48 | : m(ListItem, {discussion: discussion}) 49 | }); 50 | })} 51 |
52 |
{loading}
53 |
54 | ); 55 | 56 | } else { 57 | return original(); 58 | } 59 | }) 60 | }, -1); 61 | 62 | 63 | // Expose compat API 64 | import extCompat from './compat'; 65 | import {compat} from '@flarum/core/forum'; 66 | 67 | Object.assign(compat, extCompat); 68 | -------------------------------------------------------------------------------- /js/src/forum/components/CardItem.js: -------------------------------------------------------------------------------- 1 | import Component from "flarum/common/Component"; 2 | import craftBadges from "../utils/craftBadges"; 3 | import getPostImage from "../helpers/getPostImage"; 4 | import craftTags from "../utils/craftTags"; 5 | import humanTime from 'flarum/common/utils/humanTime'; 6 | import icon from 'flarum/common/helpers/icon'; 7 | import username from 'flarum/common/helpers/username'; 8 | import Dropdown from 'flarum/common/components/Dropdown'; 9 | import DiscussionControls from 'flarum/forum/utils/DiscussionControls'; 10 | import Link from 'flarum/common/components/Link'; 11 | import {truncate} from 'flarum/common/utils/string'; 12 | import LastReplies from './LastReplies'; 13 | 14 | 15 | export default class cardItem extends Component { 16 | 17 | oninit(vnode) { 18 | super.oninit(vnode); 19 | this.discussion = this.attrs.discussion; 20 | } 21 | 22 | view() { 23 | const discussion = this.discussion; 24 | const settings = JSON.parse(app.forum.attribute('dem13nDiscussionCards')); 25 | const isRead = settings.markCards === 1 && (!discussion.isRead() && app.session.user) ? 'Unread' : ''; 26 | const attrs = {}; 27 | attrs.className = "wrapImg" + (settings.cardFooter === 1 ? " After" : ''); 28 | const image = getPostImage(discussion.firstPost()); 29 | const media = image 30 | ? {discussion.title()} 34 | :
35 | 36 | return ( 37 |
40 | {DiscussionControls.controls(discussion, this).toArray().length 41 | ? m(Dropdown, { 42 | icon: 'fas fa-ellipsis-v', 43 | className: 'DiscussionListItem-controls', 44 | buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right', 45 | }, DiscussionControls.controls(discussion, this).toArray()) 46 | : ''} 47 | 49 | {settings.cardBadges === 1 50 | ? craftBadges(discussion.badges().toArray()) 51 | : ''} 52 | 53 |
54 | {settings.Views === 1 && !isNaN(discussion.views()) 55 | ?
56 | {icon('fas fa-eye', {className: 'labelIcon'})} 57 | {discussion.views()} 58 |
59 | : ''} 60 | {media} 61 | 62 | {settings.cardFooter === 1 63 | ?
64 |
65 | {username(discussion.user())} 66 |
67 |
68 | {humanTime(discussion.createdAt())} 69 |
70 |
71 | : ''} 72 | 73 |
74 | 75 |
{craftTags(discussion.tags())}
76 |

{discussion.title()}

77 | {settings.previewText === 1 && discussion.firstPost() 78 | ?
{truncate(discussion.firstPost().contentPlain(), 150)}
79 | : ''} 80 | 81 | {settings.Replies === 1 82 | ?
83 | 86 |
87 |
88 | {m(LastReplies, {discussion: discussion})} 89 |
90 |
91 | {app.translator.trans('dem13n.forum.replies', {count: discussion.replyCount() || '0'})} 92 |
93 |
94 |
95 | {icon('fas fa-angle-right')} 96 |
97 | 98 |
99 | : ''} 100 | 101 | 102 |
103 | ); 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /js/src/forum/components/ListItem.js: -------------------------------------------------------------------------------- 1 | import Component from "flarum/common/Component"; 2 | import craftBadges from "../utils/craftBadges"; 3 | import getPostImage from "../helpers/getPostImage"; 4 | import craftTags from "../utils/craftTags"; 5 | import humanTime from 'flarum/common/utils/humanTime'; 6 | import icon from 'flarum/common/helpers/icon'; 7 | import username from 'flarum/common/helpers/username'; 8 | import Dropdown from 'flarum/common/components/Dropdown'; 9 | import DiscussionControls from 'flarum/forum/utils/DiscussionControls'; 10 | import Link from 'flarum/common/components/Link'; 11 | import {truncate} from 'flarum/common/utils/string'; 12 | import LastReplies from './LastReplies'; 13 | 14 | 15 | export default class listItem extends Component { 16 | 17 | oninit(vnode) { 18 | super.oninit(vnode); 19 | } 20 | 21 | view() { 22 | const discussion = this.attrs.discussion; 23 | const settings = JSON.parse(app.forum.attribute('dem13nDiscussionCards')); 24 | const isRead = settings.markCards === 1 && (!discussion.isRead() && app.session.user) ? 'Unread' : ''; 25 | const attrs = {}; 26 | attrs.className = "wrapImg" + (settings.cardFooter === 1 ? " After" : ''); 27 | const image = getPostImage(discussion.firstPost()); 28 | const media = image 29 | ? {discussion.title()} 33 | :
34 | 35 | return ( 36 |
39 | {DiscussionControls.controls(discussion, this).toArray().length 40 | ? m(Dropdown, { 41 | icon: 'fas fa-ellipsis-v', 42 | className: 'DiscussionListItem-controls', 43 | buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right', 44 | }, DiscussionControls.controls(discussion, this).toArray()) 45 | : ''} 46 | 48 | 49 | {settings.cardBadges === 1 50 | ? craftBadges(discussion.badges().toArray()) 51 | : ''} 52 | 53 |
54 | 55 |
56 |
57 | {settings.Views === 1 && !isNaN(discussion.views()) 58 | ?
59 | {icon('fas fa-eye', {className: 'labelIcon'})} 60 | {discussion.views()} 61 |
62 | : ''} 63 | {media} 64 | 65 | {settings.cardFooter === 1 66 | ?
67 |
68 | {username(discussion.user())} 69 |
70 |
71 | {humanTime(discussion.createdAt())} 72 |
73 |
74 | : ''} 75 | 76 |
77 |
78 | 79 |
80 | 81 |
82 |
83 |

{truncate(discussion.title(), 80)}

84 |
85 |
{craftTags(discussion.tags())}
86 |
87 | 88 | {settings.previewText === 1 && discussion.firstPost() 89 | ?
{truncate(discussion.firstPost().contentPlain(), 150)}
90 | : ''} 91 | 92 | {app.screen() === 'phone' && settings.Replies === 1 93 | ?
94 | 97 |
98 |
99 | {m(LastReplies, {discussion: discussion})} 100 |
101 |
102 | {app.translator.trans('dem13n.forum.replies', {count: discussion.replyCount() || '0'})} 103 |
104 |
105 |
106 | {icon('fas fa-angle-right')} 107 |
108 | 109 |
110 | : settings.Replies === 1 ? 111 |
112 | {icon('fas fa-comment', {className: 'labelIcon'})} 113 | {discussion.replyCount()} 114 |
: '' 115 | } 116 |
117 |
118 | 119 |
120 | ); 121 | 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /js/dist/admin.js: -------------------------------------------------------------------------------- 1 | module.exports=function(t){var n={};function e(a){if(n[a])return n[a].exports;var o=n[a]={i:a,l:!1,exports:{}};return t[a].call(o.exports,o,o.exports,e),o.l=!0,o.exports}return e.m=t,e.c=n,e.d=function(t,n,a){e.o(t,n)||Object.defineProperty(t,n,{enumerable:!0,get:a})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,n){if(1&n&&(t=e(t)),8&n)return t;if(4&n&&"object"==typeof t&&t&&t.__esModule)return t;var a=Object.create(null);if(e.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:t}),2&n&&"string"!=typeof t)for(var o in t)e.d(a,o,function(n){return t[n]}.bind(null,o));return a},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},e.p="",e(e.s=28)}([function(t,n){t.exports=flarum.core.compat.app},function(t,n){t.exports=flarum.core.compat["common/helpers/icon"]},function(t,n,e){"use strict";function a(t,n){return(a=Object.setPrototypeOf||function(t,n){return t.__proto__=n,t})(t,n)}function o(t,n){t.prototype=Object.create(n.prototype),t.prototype.constructor=t,a(t,n)}e.d(n,"a",(function(){return o}))},function(t,n){t.exports=flarum.core.compat["common/components/Switch"]},function(t,n){t.exports=flarum.core.compat["common/Component"]},,function(t,n){t.exports=flarum.core.compat["common/components/Button"]},,function(t,n){t.exports=flarum.core.compat["tags/utils/sortTags"]},,,,,function(t,n){t.exports=flarum.core.compat["admin/components/ExtensionPage"]},function(t,n){t.exports=flarum.core.compat["admin/utils/saveSettings"]},,,,,,,,,function(t,n){t.exports=flarum.core.compat["admin/components/UploadImageButton"]},function(t,n){t.exports=flarum.core.compat["admin/components/LoadingModal"]},function(t,n){t.exports=flarum.core.compat["common/utils/Stream"]},function(t,n){t.exports=flarum.core.compat["common/utils/withAttr"]},,function(t,n,e){"use strict";e.r(n);var a=e(0),o=e.n(a),r=e(2),i=e(13),s=e.n(i),u=e(6),c=e.n(u),l=e(14),d=e.n(l),p=e(3),f=e.n(p),g=e(1),h=e.n(g),_=e(23),b=e.n(_),x=e(4),y=e.n(x),v=(e(25),e(26),e(8)),w=e.n(v),F=function(t){function n(){return t.apply(this,arguments)||this}Object(r.a)(n,t);var e=n.prototype;return e.oninit=function(n){t.prototype.oninit.call(this,n),this.tags=this.attrs.tags},e.view=function(){var t=this;return m(".TagGroup",[m("ul.TagList",[w()(o.a.store.all("tags")).map((function(n){var e=t.tags;return[m(f.a,{id:n.slug(),state:!!e.length&&e.includes(n.slug()),onchange:function(){this.state?-1!==e.indexOf(this.id)&&e.splice(e.indexOf(this.id),1):e.push(this.id)},className:"switchTags"},m("li",{style:{color:n.color(),lineHeight:"20px",fontSize:"16px",marginLeft:n.isPrimary()||null===n.position()?0:"20px"}},h()(n.icon()),n.name()))]}))])])},n}(y.a),O=e(24),P=e.n(O),C=function(t){function n(){return t.apply(this,arguments)||this}Object(r.a)(n,t);var e=n.prototype;return e.oninit=function(n){t.prototype.oninit.call(this,n),this.settings=JSON.parse(o.a.data.settings.dem13n_discussion_cards||null)},e.content=function(){if(!this.settings)return m(".ExtensionPage-settings",[m(".container",{style:{color:"red",fontWeight:"bold"}},h()("fas fa-exclamation-triangle",{style:{fontSize:"24px",marginRight:"10px"}}),o.a.translator.trans("dem13n.admin.settings.settings_error"))]);var t=this.settings;return o.a.forum.data.attributes.dem13n_discussion_cards_default_imageUrl=o.a.forum.attribute("baseUrl")+"/assets/"+o.a.data.settings.dem13n_discussion_cards_default_image_path,[m(".ExtensionPage-settings",[m(".container",[m("Form",{onsubmit:this.onsubmit.bind(this)},[m(".Form-group",[m("label",o.a.translator.trans("dem13n.admin.settings.default_img")),m(b.a,{name:"dem13n_discussion_cards_default_image"})]),m(".Form-group",[m(f.a,{state:t.previewText||!1,onchange:function(){t.previewText^=!0}},o.a.translator.trans("dem13n.admin.settings.preview_text"))]),m(".Form-group",[m(f.a,{state:t.cardBadges||!1,onchange:function(){t.cardBadges^=!0}},o.a.translator.trans("dem13n.admin.settings.badges"))]),m(".Form-group",[m(f.a,{state:t.cardFooter,onchange:function(){t.cardFooter^=!0}},o.a.translator.trans("dem13n.admin.settings.actor_info"))]),m(".Form-group",[m(f.a,{state:t.Replies,onchange:function(){t.Replies^=!0}},o.a.translator.trans("dem13n.admin.settings.show_replies"))]),m(".Form-group",[m(f.a,{state:t.onIndexPage,onchange:function(){t.onIndexPage^=!0}},o.a.translator.trans("dem13n.admin.settings.output_on_index_page"))]),m(".Form-group",[m(f.a,{state:t.Views,onchange:function(){t.Views^=!0}},o.a.translator.trans("dem13n.admin.settings.show_views"))]),m(".Form-group",[m(f.a,{state:t.markCards,onchange:function(){t.markCards^=!0}},o.a.translator.trans("dem13n.admin.settings.mark_cards"))]),m(".Form-group",[m("label",o.a.translator.trans("dem13n.admin.settings.desktop_card_width",{percent:t.desktopCardWidth||49})),m("input",{type:"range",min:1,max:100,step:.1,value:t.desktopCardWidth||49,oninput:function(n){t.desktopCardWidth=n.target.value},style:{width:"100%"}})]),m(".Form-group",[m("label",o.a.translator.trans("dem13n.admin.settings.tablet_card_width",{percent:t.tabletCardWidth||49})),m("input",{type:"range",min:1,max:100,step:.1,value:t.tabletCardWidth||49,oninput:function(n){t.tabletCardWidth=n.target.value},style:{width:"100%"}})]),m(".Form-group",[m("label",o.a.translator.trans("dem13n.admin.settings.small_cards")),m("input.FormControl",{type:"number",min:0,value:t.smallCards,oninput:function(n){t.smallCards=n.target.value}})]),m(".Form-group",[m("label",o.a.translator.trans("dem13n.admin.settings.choose_tags")),m(F,{tags:t.allowedTags}),m(c.a,{type:"submit",className:"Button Button--primary",loading:this.loading},o.a.translator.trans("core.admin.settings.submit_button"))])])])])]},e.onsubmit=function(t){t.preventDefault(),this.loading||(this.loading=!0,d()({dem13n_discussion_cards:JSON.stringify(this.settings)}),o.a.modal.show(P.a),o.a.request({method:"DELETE",url:o.a.forum.attribute("apiUrl")+"/cache"}).then((function(){return window.location.reload()})))},n}(s.a);o.a.initializers.add("dem13n/discussion/cards",(function(){o.a.extensionData.for("dem13n-discussion-cards").registerPage(C)}))}]); 2 | //# sourceMappingURL=admin.js.map -------------------------------------------------------------------------------- /js/src/admin/components/Settings.js: -------------------------------------------------------------------------------- 1 | import ExtensionPage from 'flarum/admin/components/ExtensionPage'; 2 | import app from 'flarum/app'; 3 | import Button from 'flarum/common/components/Button'; 4 | import saveSettings from 'flarum/admin/utils/saveSettings'; 5 | import Switch from 'flarum/common/components/Switch'; 6 | import icon from 'flarum/common/helpers/icon'; 7 | import UploadImageButton from 'flarum/admin/components/UploadImageButton'; 8 | import SwitchTagList from './switchTagList'; 9 | import LoadingModal from 'flarum/admin/components/LoadingModal'; 10 | 11 | 12 | 13 | export default class Settings extends ExtensionPage { 14 | 15 | oninit(vnode) { 16 | super.oninit(vnode); 17 | this.settings = JSON.parse(app.data.settings.dem13n_discussion_cards || null); 18 | } 19 | 20 | content() { 21 | 22 | if (!this.settings) { 23 | return m('.ExtensionPage-settings', [ 24 | m('.container', { 25 | style: {color: 'red', fontWeight: 'bold'} 26 | }, 27 | icon('fas fa-exclamation-triangle', {style: {fontSize: '24px', marginRight: '10px'}}), 28 | app.translator.trans('dem13n.admin.settings.settings_error')) 29 | ]); 30 | } 31 | 32 | const settings = this.settings; 33 | app.forum.data.attributes.dem13n_discussion_cards_default_imageUrl = 34 | app.forum.attribute("baseUrl") + "/assets/" + 35 | app.data.settings.dem13n_discussion_cards_default_image_path; 36 | 37 | return [ 38 | m('.ExtensionPage-settings', [ 39 | m('.container', [ 40 | m('Form', { 41 | onsubmit: this.onsubmit.bind(this), 42 | }, [ 43 | m('.Form-group', [ 44 | m('label', app.translator.trans('dem13n.admin.settings.default_img')), 45 | m(UploadImageButton, {name: "dem13n_discussion_cards_default_image"}), 46 | ]), 47 | m('.Form-group', [ 48 | m(Switch, { 49 | state: settings.previewText || false, 50 | onchange: () => { 51 | settings.previewText ^= true 52 | }, 53 | }, app.translator.trans('dem13n.admin.settings.preview_text') 54 | ), 55 | ]), 56 | m('.Form-group', [ 57 | m(Switch, { 58 | state: settings.cardBadges || false, 59 | onchange: () => { 60 | settings.cardBadges ^= true 61 | }, 62 | }, 63 | app.translator.trans('dem13n.admin.settings.badges') 64 | ), 65 | ]), 66 | m('.Form-group', [ 67 | m(Switch, { 68 | state: settings.cardFooter, 69 | onchange: () => { 70 | settings.cardFooter ^= true 71 | }, 72 | }, app.translator.trans('dem13n.admin.settings.actor_info') 73 | ), 74 | ]), 75 | m('.Form-group', [ 76 | m(Switch, { 77 | state: settings.Replies, 78 | onchange: () => { 79 | settings.Replies ^= true 80 | }, 81 | }, app.translator.trans('dem13n.admin.settings.show_replies') 82 | ), 83 | ]), 84 | m('.Form-group', [ 85 | m(Switch, { 86 | state: settings.onIndexPage, 87 | onchange: () => { 88 | settings.onIndexPage ^= true 89 | }, 90 | }, app.translator.trans('dem13n.admin.settings.output_on_index_page') 91 | ), 92 | ]), 93 | m('.Form-group', [ 94 | m(Switch, { 95 | state: settings.Views, 96 | onchange: () => { 97 | settings.Views ^= true 98 | }, 99 | }, app.translator.trans('dem13n.admin.settings.show_views') 100 | ), 101 | ]), 102 | m('.Form-group', [ 103 | m(Switch, { 104 | state: settings.markCards, 105 | onchange: () => { 106 | settings.markCards ^= true 107 | }, 108 | }, app.translator.trans('dem13n.admin.settings.mark_cards') 109 | ), 110 | ]), 111 | m('.Form-group', [ 112 | m('label', app.translator.trans('dem13n.admin.settings.desktop_card_width', {percent: settings.desktopCardWidth || 49})), 113 | m('input', { 114 | type: 'range', 115 | min: 1, 116 | max: 100, 117 | step: 0.1, 118 | value: settings.desktopCardWidth || 49, 119 | oninput: e => { 120 | settings.desktopCardWidth = e.target.value; 121 | }, 122 | style: {width: '100%'} 123 | }), 124 | ]), 125 | m('.Form-group', [ 126 | m('label', app.translator.trans('dem13n.admin.settings.tablet_card_width', {percent: settings.tabletCardWidth || 49})), 127 | m('input', { 128 | type: 'range', 129 | min: 1, 130 | max: 100, 131 | step: 0.1, 132 | value: settings.tabletCardWidth || 49, 133 | oninput: e => { 134 | settings.tabletCardWidth = e.target.value; 135 | }, 136 | style: {width: '100%'} 137 | }), 138 | ]), 139 | m('.Form-group', [ 140 | m('label', app.translator.trans('dem13n.admin.settings.small_cards')), 141 | m('input.FormControl', { 142 | type: 'number', 143 | min: 0, 144 | value: settings.smallCards, 145 | oninput: e => { 146 | settings.smallCards = e.target.value; 147 | } 148 | }), 149 | ]), 150 | m('.Form-group', [ 151 | m('label', app.translator.trans('dem13n.admin.settings.choose_tags')), 152 | m(SwitchTagList, {tags: settings.allowedTags}), 153 | m(Button, { 154 | type: 'submit', 155 | className: 'Button Button--primary', 156 | loading: this.loading 157 | }, app.translator.trans('core.admin.settings.submit_button') 158 | ), 159 | ]), 160 | ]), 161 | ]) 162 | ]) 163 | ] 164 | 165 | 166 | } 167 | 168 | onsubmit(e) { 169 | e.preventDefault(); 170 | if (this.loading) return; 171 | this.loading = true; 172 | saveSettings({ 173 | dem13n_discussion_cards: JSON.stringify(this.settings), 174 | }); 175 | 176 | app.modal.show(LoadingModal); 177 | app.request({ 178 | method: 'DELETE', 179 | url: app.forum.attribute('apiUrl') + '/cache', 180 | }) 181 | .then(() => window.location.reload()); 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /js/dist/forum.js: -------------------------------------------------------------------------------- 1 | module.exports=function(t){var s={};function e(a){if(s[a])return s[a].exports;var n=s[a]={i:a,l:!1,exports:{}};return t[a].call(n.exports,n,n.exports,e),n.l=!0,n.exports}return e.m=t,e.c=s,e.d=function(t,s,a){e.o(t,s)||Object.defineProperty(t,s,{enumerable:!0,get:a})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,s){if(1&s&&(t=e(t)),8&s)return t;if(4&s&&"object"==typeof t&&t&&t.__esModule)return t;var a=Object.create(null);if(e.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:t}),2&s&&"string"!=typeof t)for(var n in t)e.d(a,n,function(s){return t[s]}.bind(null,n));return a},e.n=function(t){var s=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(s,"a",s),s},e.o=function(t,s){return Object.prototype.hasOwnProperty.call(t,s)},e.p="",e(e.s=27)}([function(t,s){t.exports=flarum.core.compat.app},function(t,s){t.exports=flarum.core.compat["common/helpers/icon"]},function(t,s,e){"use strict";function a(t,s){return(a=Object.setPrototypeOf||function(t,s){return t.__proto__=s,t})(t,s)}function n(t,s){t.prototype=Object.create(s.prototype),t.prototype.constructor=t,a(t,s)}e.d(s,"a",(function(){return n}))},,function(t,s){t.exports=flarum.core.compat["common/Component"]},function(t,s){t.exports=flarum.core.compat["common/components/Link"]},function(t,s){t.exports=flarum.core.compat["common/components/Button"]},function(t,s){t.exports=flarum.core.compat["forum/utils/DiscussionControls"]},function(t,s){t.exports=flarum.core.compat["tags/utils/sortTags"]},function(t,s){t.exports=flarum.core.compat["common/utils/string"]},function(t,s){t.exports=flarum.core.compat["common/utils/humanTime"]},function(t,s){t.exports=flarum.core.compat["common/helpers/username"]},function(t,s){t.exports=flarum.core.compat["common/components/Dropdown"]},,,function(t,s){t.exports=flarum.core.compat.extend},function(t,s){t.exports=flarum.core.compat["forum/components/IndexPage"]},function(t,s){t.exports=flarum.core.compat["forum/components/DiscussionList"]},function(t,s){t.exports=flarum.core.compat["forum/states/DiscussionListState"]},function(t,s){t.exports=flarum.core.compat["common/components/LoadingIndicator"]},function(t,s){t.exports=flarum.core.compat["common/components/Placeholder"]},function(t,s){t.exports=flarum.core.compat["common/helpers/avatar"]},function(t,s){t.exports=flarum.core},,,,,function(t,s,e){"use strict";e.r(s);var a=e(0),n=e.n(a),o=e(15),r=e(17),i=e.n(r),c=e(18),u=e.n(c),l=e(16),d=e.n(l),p=e(19),f=e.n(p),v=e(20),g=e.n(v),N=e(6),h=e.n(N),b=e(2),y=e(4),x=e.n(y),w=e(1),L=e.n(w);function P(t){if(t.length)return[m(".cardBadges",[t.map((function(t){return[m("span.cardBadge.Badge.Badge--"+t.attrs.type,{"data-original-title":t.attrs.label[0],oncreate:function(t){return $(t.dom).tooltip({placement:"right"})}},[L()(t.attrs.icon)])]}))])]}function C(t,s){void 0===s&&(s=1);var e=app.forum.attribute("dem13nDiscussionCardsDefaultImage"),a=app.forum.attribute("baseUrl")+"/assets/"+e;if(t){var n=//.exec(t.contentHtml());return"number"==typeof s&&s>0?n?n[s]:e?a:null:"~"===s?n:null}}var O=e(5),S=e.n(O),j=e(8),A=e.n(j);function D(t){if(t)return[A()(t).map((function(t){return[m(S.a,{className:"cardTag",style:{backgroundColor:t.color()},href:app.route("tag",{tags:t.slug()})},t.name())]}))]}var I=e(10),B=e.n(I),T=e(11),_=e.n(T),R=e(12),k=e.n(R),F=e(7),H=e.n(F),M=e(9),V=e(21),z=e.n(V),J=function(t){function s(){return t.apply(this,arguments)||this}Object(b.a)(s,t);var e=s.prototype;return e.oninit=function(s){t.prototype.oninit.call(this,s),this.discussion=this.attrs.discussion},e.view=function(){return this.discussion.posts().splice(-10).filter((function(t){return!t.isHidden()&&1!==t.number()&&"comment"===t.contentType()})).sort((function(t,s){return s.createdAt()-t.createdAt()})).map((function(t){return t.user()})).filter((function(t,s,e){return e.indexOf(t)===s})).reverse().splice(-3).map((function(t){return z()(t,{className:"Avatar--mini"})}))},s}(x.a),U=function(t){function s(){return t.apply(this,arguments)||this}Object(b.a)(s,t);var e=s.prototype;return e.oninit=function(s){t.prototype.oninit.call(this,s),this.discussion=this.attrs.discussion},e.view=function(){var t=this.discussion,s=JSON.parse(app.forum.attribute("dem13nDiscussionCards")),e=1===s.markCards&&!t.isRead()&&app.session.user?"Unread":"",a={};a.className="wrapImg"+(1===s.cardFooter?" After":"");var n=C(t.firstPost()),o=n?m("img",{src:n,className:"previewCardImg",alt:t.title(),loading:"lazy"}):m("div",{className:"imgStub"});return m("div",{key:t.id(),"data-id":t.id(),className:"CardsListItem Card "+e+(t.isHidden()?" Hidden":"")},H.a.controls(t,this).toArray().length?m(k.a,{icon:"fas fa-ellipsis-v",className:"DiscussionListItem-controls",buttonClassName:"Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right"},H.a.controls(t,this).toArray()):"",m(S.a,{href:app.route.discussion(t,0),className:"cardLink"},1===s.cardBadges?P(t.badges().toArray()):"",m("div",a,1!==s.Views||isNaN(t.views())?"":m("div",{className:"imageLabel discussionViews"},L()("fas fa-eye",{className:"labelIcon"}),t.views()),o,1===s.cardFooter?m("div",{className:"cardFoot"},m("div",{className:"Author"},_()(t.user())),m("div",{className:"Date"},B()(t.createdAt()))):""),m("div",{className:"cardTags"},D(t.tags())),m("div",{className:"cardTitle"},m("h2",null,t.title())),1===s.previewText&&t.firstPost()?m("div",{className:"previewPost"},Object(M.truncate)(t.firstPost().contentPlain(),150)):"",1===s.Replies?m("div",{className:"cardSpacer"},m(S.a,{className:"Replies",href:app.route.discussion(t,t.lastPostNumber())},m("div",{className:"Left"},m("div",{className:"Avatars"},m(J,{discussion:t})),m("div",{className:"Repcount"},app.translator.trans("dem13n.forum.replies",{count:t.replyCount()||"0"}))),m("div",{className:"Arrow"},L()("fas fa-angle-right")))):""))},s}(x.a),q=function(t){function s(){return t.apply(this,arguments)||this}Object(b.a)(s,t);var e=s.prototype;return e.oninit=function(s){t.prototype.oninit.call(this,s)},e.view=function(){var t=this.attrs.discussion,s=JSON.parse(app.forum.attribute("dem13nDiscussionCards")),e=1===s.markCards&&!t.isRead()&&app.session.user?"Unread":"",a={};a.className="wrapImg"+(1===s.cardFooter?" After":"");var n=C(t.firstPost()),o=n?m("img",{src:n,className:"previewCardImg",alt:t.title(),loading:"lazy"}):m("div",{className:"imgStub"});return m("div",{key:t.id(),"data-id":t.id(),className:"CardsListItem List "+e+(t.isHidden()?" Hidden":"")},H.a.controls(t,this).toArray().length?m(k.a,{icon:"fas fa-ellipsis-v",className:"DiscussionListItem-controls",buttonClassName:"Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right"},H.a.controls(t,this).toArray()):"",m(S.a,{href:app.route.discussion(t,0),className:"cardLink"},1===s.cardBadges?P(t.badges().toArray()):"",m("div",{className:"cardGrid"},m("div",{className:"rowSpan-3 colSpan"},m("div",a,1!==s.Views||isNaN(t.views())?"":m("div",{className:"imageLabel discussionViews"},L()("fas fa-eye",{className:"labelIcon"}),t.views()),o,1===s.cardFooter?m("div",{className:"cardFoot"},m("div",{className:"Author"},_()(t.user())),m("div",{className:"Date"},B()(t.createdAt()))):"")),m("div",{className:"rowSpan-3 colSpan-2"},m("div",{className:"flexBox"},m("div",{className:"cardTitle"},m("h2",{title:t.title(),className:"title"},Object(M.truncate)(t.title(),80))),m("div",{className:"cardTags"},D(t.tags()))),1===s.previewText&&t.firstPost()?m("div",{className:"previewPost"},Object(M.truncate)(t.firstPost().contentPlain(),150)):"","phone"===app.screen()&&1===s.Replies?m("div",{className:"cardSpacer"},m(S.a,{className:"Replies",href:app.route.discussion(t,t.lastPostNumber())},m("div",{className:"Left"},m("div",{className:"Avatars"},m(J,{discussion:t})),m("div",{className:"Repcount"},app.translator.trans("dem13n.forum.replies",{count:t.replyCount()||"0"}))),m("div",{className:"Arrow"},L()("fas fa-angle-right")))):1===s.Replies?m("div",{className:"imageLabel discussionReplyCount"},L()("fas fa-comment",{className:"labelIcon"}),t.replyCount()):""))))},s}(x.a),E={"dem13n/discussion/cards/components/CardItem":U,"dem13n/discussion/cards/components/ListItem":q,"dem13n/discussion/cards/components/LastReplies":J,"dem13n/discussion/cards/utils/craftTags":D,"dem13n/discussion/cards/utils/craftBadges":P},G=e(22);n.a.initializers.add("dem13n/discussion/cards",(function(){Object(o.extend)(u.a.prototype,"requestParams",(function(t){n.a.current.matches(d.a)&&t.include.push(["firstPost","posts","posts.user"])})),Object(o.override)(i.a.prototype,"view",(function(t){var s,e=JSON.parse(n.a.forum.attribute("dem13nDiscussionCards")),a=this.attrs.state,o=a.getParams();if(a.isInitialLoading()||a.isLoadingNext()?s=m(f.a,null):a.hasNext()&&(s=h.a.component({className:"Button",onclick:a.loadNext.bind(a)},n.a.translator.trans("core.forum.discussion_list.load_more_button"))),a.isEmpty()){var r=n.a.translator.trans("core.forum.discussion_list.empty_text");return m("div",{className:"DiscussionList"},m(g.a,{text:r}))}return n.a.current.matches(d.a)&&(e.allowedTags.length&&e.allowedTags.includes(o.tags)||!o.tags&&1===e.onIndexPage)?m("div",{className:"DiscussionList"+(a.isSearchResults()?" DiscussionList--searchResults":"")},m("div",{class:"DiscussionList-discussions flexCard"},a.getPages().map((function(t,s){return t.items.map((function(t,a){return a {\r\n const allowedTags = this.tags;\r\n return [\r\n m(Switch, {\r\n id: tag.slug(),\r\n state: (allowedTags.length) ? allowedTags.includes(tag.slug()) : false,\r\n onchange: function () {\r\n this.state\r\n ? allowedTags.indexOf(this.id) !== -1 && allowedTags.splice(allowedTags.indexOf(this.id), 1)\r\n : allowedTags.push(this.id);\r\n },\r\n className: 'switchTags'\r\n }, m(\"li\", {\r\n style: {\r\n color: tag.color(),\r\n lineHeight: '20px',\r\n fontSize: '16px',\r\n marginLeft: !(tag.isPrimary() || tag.position() === null) ? '20px' : 0,\r\n }\r\n }, icon(tag.icon()), tag.name())\r\n )\r\n ];\r\n })\r\n ])\r\n ])\r\n\r\n }\r\n\r\n}\r\n","import ExtensionPage from 'flarum/admin/components/ExtensionPage';\r\nimport app from 'flarum/app';\r\nimport Button from 'flarum/common/components/Button';\r\nimport saveSettings from 'flarum/admin/utils/saveSettings';\r\nimport Switch from 'flarum/common/components/Switch';\r\nimport icon from 'flarum/common/helpers/icon';\r\nimport UploadImageButton from 'flarum/admin/components/UploadImageButton';\r\nimport SwitchTagList from './switchTagList';\r\nimport LoadingModal from 'flarum/admin/components/LoadingModal';\r\n\r\n\r\n\r\nexport default class Settings extends ExtensionPage {\r\n\r\n oninit(vnode) {\r\n super.oninit(vnode);\r\n this.settings = JSON.parse(app.data.settings.dem13n_discussion_cards || null);\r\n }\r\n\r\n content() {\r\n\r\n if (!this.settings) {\r\n return m('.ExtensionPage-settings', [\r\n m('.container', {\r\n style: {color: 'red', fontWeight: 'bold'}\r\n },\r\n icon('fas fa-exclamation-triangle', {style: {fontSize: '24px', marginRight: '10px'}}),\r\n app.translator.trans('dem13n.admin.settings.settings_error'))\r\n ]);\r\n }\r\n\r\n const settings = this.settings;\r\n app.forum.data.attributes.dem13n_discussion_cards_default_imageUrl =\r\n app.forum.attribute(\"baseUrl\") + \"/assets/\" +\r\n app.data.settings.dem13n_discussion_cards_default_image_path;\r\n\r\n return [\r\n m('.ExtensionPage-settings', [\r\n m('.container', [\r\n m('Form', {\r\n onsubmit: this.onsubmit.bind(this),\r\n }, [\r\n m('.Form-group', [\r\n m('label', app.translator.trans('dem13n.admin.settings.default_img')),\r\n m(UploadImageButton, {name: \"dem13n_discussion_cards_default_image\"}),\r\n ]),\r\n m('.Form-group', [\r\n m(Switch, {\r\n state: settings.previewText || false,\r\n onchange: () => {\r\n settings.previewText ^= true\r\n },\r\n }, app.translator.trans('dem13n.admin.settings.preview_text')\r\n ),\r\n ]),\r\n m('.Form-group', [\r\n m(Switch, {\r\n state: settings.cardBadges || false,\r\n onchange: () => {\r\n settings.cardBadges ^= true\r\n },\r\n },\r\n app.translator.trans('dem13n.admin.settings.badges')\r\n ),\r\n ]),\r\n m('.Form-group', [\r\n m(Switch, {\r\n state: settings.cardFooter,\r\n onchange: () => {\r\n settings.cardFooter ^= true\r\n },\r\n }, app.translator.trans('dem13n.admin.settings.actor_info')\r\n ),\r\n ]),\r\n m('.Form-group', [\r\n m(Switch, {\r\n state: settings.Replies,\r\n onchange: () => {\r\n settings.Replies ^= true\r\n },\r\n }, app.translator.trans('dem13n.admin.settings.show_replies')\r\n ),\r\n ]),\r\n m('.Form-group', [\r\n m(Switch, {\r\n state: settings.onIndexPage,\r\n onchange: () => {\r\n settings.onIndexPage ^= true\r\n },\r\n }, app.translator.trans('dem13n.admin.settings.output_on_index_page')\r\n ),\r\n ]),\r\n m('.Form-group', [\r\n m(Switch, {\r\n state: settings.Views,\r\n onchange: () => {\r\n settings.Views ^= true\r\n },\r\n }, app.translator.trans('dem13n.admin.settings.show_views')\r\n ),\r\n ]),\r\n m('.Form-group', [\r\n m(Switch, {\r\n state: settings.markCards,\r\n onchange: () => {\r\n settings.markCards ^= true\r\n },\r\n }, app.translator.trans('dem13n.admin.settings.mark_cards')\r\n ),\r\n ]),\r\n m('.Form-group', [\r\n m('label', app.translator.trans('dem13n.admin.settings.desktop_card_width', {percent: settings.desktopCardWidth || 49})),\r\n m('input', {\r\n type: 'range',\r\n min: 1,\r\n max: 100,\r\n step: 0.1,\r\n value: settings.desktopCardWidth || 49,\r\n oninput: e => {\r\n settings.desktopCardWidth = e.target.value;\r\n },\r\n style: {width: '100%'}\r\n }),\r\n ]),\r\n m('.Form-group', [\r\n m('label', app.translator.trans('dem13n.admin.settings.tablet_card_width', {percent: settings.tabletCardWidth || 49})),\r\n m('input', {\r\n type: 'range',\r\n min: 1,\r\n max: 100,\r\n step: 0.1,\r\n value: settings.tabletCardWidth || 49,\r\n oninput: e => {\r\n settings.tabletCardWidth = e.target.value;\r\n },\r\n style: {width: '100%'}\r\n }),\r\n ]),\r\n m('.Form-group', [\r\n m('label', app.translator.trans('dem13n.admin.settings.small_cards')),\r\n m('input.FormControl', {\r\n type: 'number',\r\n min: 0,\r\n value: settings.smallCards,\r\n oninput: e => {\r\n settings.smallCards = e.target.value;\r\n }\r\n }),\r\n ]),\r\n m('.Form-group', [\r\n m('label', app.translator.trans('dem13n.admin.settings.choose_tags')),\r\n m(SwitchTagList, {tags: settings.allowedTags}),\r\n m(Button, {\r\n type: 'submit',\r\n className: 'Button Button--primary',\r\n loading: this.loading\r\n }, app.translator.trans('core.admin.settings.submit_button')\r\n ),\r\n ]),\r\n ]),\r\n ])\r\n ])\r\n ]\r\n\r\n\r\n }\r\n\r\n onsubmit(e) {\r\n e.preventDefault();\r\n if (this.loading) return;\r\n this.loading = true;\r\n saveSettings({\r\n dem13n_discussion_cards: JSON.stringify(this.settings),\r\n });\r\n\r\n app.modal.show(LoadingModal);\r\n app.request({\r\n method: 'DELETE',\r\n url: app.forum.attribute('apiUrl') + '/cache',\r\n })\r\n .then(() => window.location.reload());\r\n }\r\n\r\n}\r\n","import app from 'flarum/app';\r\nimport Settings from './components/Settings';\r\n\r\n\r\napp.initializers.add('dem13n/discussion/cards', () => {\r\n app.extensionData\r\n .for('dem13n-discussion-cards')\r\n .registerPage(Settings)\r\n});\r\n\r\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /js/dist/forum.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://@dem13n/discussion/cards/webpack/bootstrap","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['app']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/helpers/icon']\"","webpack://@dem13n/discussion/cards/./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://@dem13n/discussion/cards/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/Component']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/components/Link']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/components/Button']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['forum/utils/DiscussionControls']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['tags/utils/sortTags']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/utils/string']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/utils/humanTime']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/helpers/username']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/components/Dropdown']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['extend']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['forum/components/IndexPage']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['forum/components/DiscussionList']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['forum/states/DiscussionListState']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/components/LoadingIndicator']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/components/Placeholder']\"","webpack://@dem13n/discussion/cards/external \"flarum.core.compat['common/helpers/avatar']\"","webpack://@dem13n/discussion/cards/external \"flarum.core\"","webpack://@dem13n/discussion/cards/./src/forum/utils/craftBadges.js","webpack://@dem13n/discussion/cards/./src/forum/helpers/getPostImage.js","webpack://@dem13n/discussion/cards/./src/forum/utils/craftTags.js","webpack://@dem13n/discussion/cards/./src/forum/components/LastReplies.js","webpack://@dem13n/discussion/cards/./src/forum/components/CardItem.js","webpack://@dem13n/discussion/cards/./src/forum/components/ListItem.js","webpack://@dem13n/discussion/cards/./src/forum/compat.js","webpack://@dem13n/discussion/cards/./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","_setPrototypeOf","setPrototypeOf","__proto__","_inheritsLoose","subClass","superClass","constructor","craftBadges","badges","length","map","badge","attrs","type","label","oncreate","vnode","$","dom","tooltip","placement","icon","getPostImage","post","image","app","forum","attribute","defaultImg","src","exec","contentHtml","craftTags","tags","sortTags","tag","className","style","backgroundColor","color","href","route","slug","LastReplies","oninit","this","discussion","view","posts","splice","filter","isHidden","number","contentType","sort","a","b","createdAt","user","self","indexOf","reverse","avatar","Component","cardItem","settings","JSON","parse","isRead","markCards","session","cardFooter","firstPost","media","alt","title","loading","id","data-id","DiscussionControls","controls","toArray","Dropdown","buttonClassName","cardBadges","Views","isNaN","views","username","humanTime","previewText","truncate","contentPlain","Replies","lastPostNumber","translator","trans","count","replyCount","listItem","screen","CardItem","ListItem","initializers","add","extend","DiscussionListState","params","current","matches","IndexPage","include","push","override","DiscussionList","original","state","getParams","isInitialLoading","isLoadingNext","hasNext","Button","component","onclick","loadNext","isEmpty","text","Placeholder","allowedTags","includes","onIndexPage","isSearchResults","class","getPages","pg","items","smallCards","assign","extCompat"],"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 = 27);\n","module.exports = flarum.core.compat['app'];","module.exports = flarum.core.compat['common/helpers/icon'];","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n setPrototypeOf(subClass, superClass);\n}","module.exports = flarum.core.compat['common/Component'];","module.exports = flarum.core.compat['common/components/Link'];","module.exports = flarum.core.compat['common/components/Button'];","module.exports = flarum.core.compat['forum/utils/DiscussionControls'];","module.exports = flarum.core.compat['tags/utils/sortTags'];","module.exports = flarum.core.compat['common/utils/string'];","module.exports = flarum.core.compat['common/utils/humanTime'];","module.exports = flarum.core.compat['common/helpers/username'];","module.exports = flarum.core.compat['common/components/Dropdown'];","module.exports = flarum.core.compat['extend'];","module.exports = flarum.core.compat['forum/components/IndexPage'];","module.exports = flarum.core.compat['forum/components/DiscussionList'];","module.exports = flarum.core.compat['forum/states/DiscussionListState'];","module.exports = flarum.core.compat['common/components/LoadingIndicator'];","module.exports = flarum.core.compat['common/components/Placeholder'];","module.exports = flarum.core.compat['common/helpers/avatar'];","module.exports = flarum.core;","import icon from 'flarum/common/helpers/icon';\r\n\r\nexport default function craftBadges(badges) {\r\n if (badges.length) {\r\n return [m('.cardBadges', [badges.map((badge) => {\r\n return [m('span.cardBadge.Badge.Badge--' + badge.attrs.type, {\r\n 'data-original-title': badge.attrs.label[0],\r\n oncreate: (vnode) => $(vnode.dom).tooltip({placement: 'right'})\r\n }, [icon(badge.attrs.icon)])]\r\n })])];\r\n }\r\n};\r\n","export default function getPostImage(post, key = 1) {\r\n\r\n const regex = //;\r\n const image = app.forum.attribute('dem13nDiscussionCardsDefaultImage');\r\n const defaultImg = app.forum.attribute(\"baseUrl\") + \"/assets/\" + image;\r\n\r\n if (post) {\r\n const src = regex.exec(post.contentHtml());\r\n if (typeof key === \"number\" && key > 0) {\r\n return (src) ? src[key] : (image ? defaultImg : null);\r\n } else if (key === '~') {\r\n return src;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n}\r\n","import Link from 'flarum/common/components/Link';\r\nimport sortTags from 'flarum/tags/utils/sortTags';\r\n\r\nexport default function craftTags(tags) {\r\n if (tags) {\r\n return [sortTags(tags).map(function (tag) {\r\n return [\r\n \r\n {tag.name()}\r\n \r\n ]\r\n })];\r\n }\r\n};\r\n","import Component from 'flarum/common/Component';\r\nimport avatar from 'flarum/common/helpers/avatar';\r\nimport icon from 'flarum/common/helpers/icon';\r\nimport Link from 'flarum/common/components/Link';\r\n\r\n\r\nexport default class LastReplies extends Component {\r\n\r\n oninit(vnode) {\r\n super.oninit(vnode);\r\n this.discussion = this.attrs.discussion;\r\n }\r\n\r\n view() {\r\n const discussion = this.discussion;\r\n\r\n // let's assume that the last 10 posts will be enough for us to identify 3 unique users\r\n const posts = discussion.posts().splice(-10);\r\n\r\n const filteredPosts = posts\r\n .filter((post) => {\r\n return !post.isHidden() && post.number() !== 1 && post.contentType() === \"comment\";\r\n })\r\n .sort((a, b) => b.createdAt() - a.createdAt());\r\n\r\n const groupedUsers = filteredPosts\r\n .map(post => post.user())\r\n .filter((user, i, self) => {\r\n return self.indexOf(user) === i\r\n })\r\n .reverse()\r\n // last 3 users\r\n .splice(-3);\r\n\r\n\r\n return groupedUsers.map(user => {\r\n return avatar(user, {className: 'Avatar--mini'})\r\n })\r\n\r\n }\r\n\r\n}\r\n","import Component from \"flarum/common/Component\";\r\nimport craftBadges from \"../utils/craftBadges\";\r\nimport getPostImage from \"../helpers/getPostImage\";\r\nimport craftTags from \"../utils/craftTags\";\r\nimport humanTime from 'flarum/common/utils/humanTime';\r\nimport icon from 'flarum/common/helpers/icon';\r\nimport username from 'flarum/common/helpers/username';\r\nimport Dropdown from 'flarum/common/components/Dropdown';\r\nimport DiscussionControls from 'flarum/forum/utils/DiscussionControls';\r\nimport Link from 'flarum/common/components/Link';\r\nimport {truncate} from 'flarum/common/utils/string';\r\nimport LastReplies from './LastReplies';\r\n\r\n\r\nexport default class cardItem extends Component {\r\n\r\n oninit(vnode) {\r\n super.oninit(vnode);\r\n this.discussion = this.attrs.discussion;\r\n }\r\n\r\n view() {\r\n const discussion = this.discussion;\r\n const settings = JSON.parse(app.forum.attribute('dem13nDiscussionCards'));\r\n const isRead = settings.markCards === 1 && (!discussion.isRead() && app.session.user) ? 'Unread' : '';\r\n const attrs = {};\r\n attrs.className = \"wrapImg\" + (settings.cardFooter === 1 ? \" After\" : '');\r\n const image = getPostImage(discussion.firstPost());\r\n const media = image\r\n ? {discussion.title()}\r\n\r\n :
\r\n\r\n return (\r\n
\r\n {DiscussionControls.controls(discussion, this).toArray().length\r\n ? m(Dropdown, {\r\n icon: 'fas fa-ellipsis-v',\r\n className: 'DiscussionListItem-controls',\r\n buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right',\r\n }, DiscussionControls.controls(discussion, this).toArray())\r\n : ''}\r\n \r\n {settings.cardBadges === 1\r\n ? craftBadges(discussion.badges().toArray())\r\n : ''}\r\n\r\n
\r\n {settings.Views === 1 && !isNaN(discussion.views())\r\n ?
\r\n {icon('fas fa-eye', {className: 'labelIcon'})}\r\n {discussion.views()}\r\n
\r\n : ''}\r\n {media}\r\n\r\n {settings.cardFooter === 1\r\n ?
\r\n
\r\n {username(discussion.user())}\r\n
\r\n
\r\n {humanTime(discussion.createdAt())}\r\n
\r\n
\r\n : ''}\r\n\r\n
\r\n\r\n
{craftTags(discussion.tags())}
\r\n

{discussion.title()}

\r\n {settings.previewText === 1 && discussion.firstPost()\r\n ?
{truncate(discussion.firstPost().contentPlain(), 150)}
\r\n : ''}\r\n\r\n {settings.Replies === 1\r\n ?
\r\n \r\n
\r\n
\r\n {m(LastReplies, {discussion: discussion})}\r\n
\r\n
\r\n {app.translator.trans('dem13n.forum.replies', {count: discussion.replyCount() || '0'})}\r\n
\r\n
\r\n
\r\n {icon('fas fa-angle-right')}\r\n
\r\n \r\n
\r\n : ''}\r\n\r\n \r\n
\r\n );\r\n\r\n }\r\n\r\n}\r\n","import Component from \"flarum/common/Component\";\r\nimport craftBadges from \"../utils/craftBadges\";\r\nimport getPostImage from \"../helpers/getPostImage\";\r\nimport craftTags from \"../utils/craftTags\";\r\nimport humanTime from 'flarum/common/utils/humanTime';\r\nimport icon from 'flarum/common/helpers/icon';\r\nimport username from 'flarum/common/helpers/username';\r\nimport Dropdown from 'flarum/common/components/Dropdown';\r\nimport DiscussionControls from 'flarum/forum/utils/DiscussionControls';\r\nimport Link from 'flarum/common/components/Link';\r\nimport {truncate} from 'flarum/common/utils/string';\r\nimport LastReplies from './LastReplies';\r\n\r\n\r\nexport default class listItem extends Component {\r\n\r\n oninit(vnode) {\r\n super.oninit(vnode);\r\n }\r\n\r\n view() {\r\n const discussion = this.attrs.discussion;\r\n const settings = JSON.parse(app.forum.attribute('dem13nDiscussionCards'));\r\n const isRead = settings.markCards === 1 && (!discussion.isRead() && app.session.user) ? 'Unread' : '';\r\n const attrs = {};\r\n attrs.className = \"wrapImg\" + (settings.cardFooter === 1 ? \" After\" : '');\r\n const image = getPostImage(discussion.firstPost());\r\n const media = image\r\n ? {discussion.title()}\r\n\r\n :
\r\n\r\n return (\r\n
\r\n {DiscussionControls.controls(discussion, this).toArray().length\r\n ? m(Dropdown, {\r\n icon: 'fas fa-ellipsis-v',\r\n className: 'DiscussionListItem-controls',\r\n buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right',\r\n }, DiscussionControls.controls(discussion, this).toArray())\r\n : ''}\r\n \r\n\r\n {settings.cardBadges === 1\r\n ? craftBadges(discussion.badges().toArray())\r\n : ''}\r\n\r\n
\r\n\r\n
\r\n
\r\n {settings.Views === 1 && !isNaN(discussion.views())\r\n ?
\r\n {icon('fas fa-eye', {className: 'labelIcon'})}\r\n {discussion.views()}\r\n
\r\n : ''}\r\n {media}\r\n\r\n {settings.cardFooter === 1\r\n ?
\r\n
\r\n {username(discussion.user())}\r\n
\r\n
\r\n {humanTime(discussion.createdAt())}\r\n
\r\n
\r\n : ''}\r\n\r\n
\r\n
\r\n\r\n
\r\n\r\n
\r\n
\r\n

{truncate(discussion.title(), 80)}

\r\n
\r\n
{craftTags(discussion.tags())}
\r\n
\r\n\r\n {settings.previewText === 1 && discussion.firstPost()\r\n ?
{truncate(discussion.firstPost().contentPlain(), 150)}
\r\n : ''}\r\n\r\n {app.screen() === 'phone' && settings.Replies === 1\r\n ?
\r\n \r\n
\r\n
\r\n {m(LastReplies, {discussion: discussion})}\r\n
\r\n
\r\n {app.translator.trans('dem13n.forum.replies', {count: discussion.replyCount() || '0'})}\r\n
\r\n
\r\n
\r\n {icon('fas fa-angle-right')}\r\n
\r\n \r\n
\r\n : settings.Replies === 1 ?\r\n
\r\n {icon('fas fa-comment', {className: 'labelIcon'})}\r\n {discussion.replyCount()}\r\n
: ''\r\n }\r\n
\r\n
\r\n \r\n
\r\n );\r\n\r\n }\r\n\r\n}\r\n","import CardItem from './components/CardItem';\r\nimport ListItem from './components/ListItem';\r\nimport LastReplies from './components/LastReplies';\r\nimport craftTags from \"./utils/craftTags\";\r\nimport craftBadges from \"./utils/craftBadges\";\r\n\r\nexport default {\r\n 'dem13n/discussion/cards/components/CardItem': CardItem,\r\n 'dem13n/discussion/cards/components/ListItem': ListItem,\r\n 'dem13n/discussion/cards/components/LastReplies': LastReplies,\r\n 'dem13n/discussion/cards/utils/craftTags': craftTags,\r\n 'dem13n/discussion/cards/utils/craftBadges': craftBadges,\r\n};\r\n","import app from 'flarum/app';\r\nimport {extend, override} from 'flarum/extend';\r\nimport DiscussionList from 'flarum/forum/components/DiscussionList';\r\nimport DiscussionListState from 'flarum/forum/states/DiscussionListState';\r\nimport IndexPage from 'flarum/forum/components/IndexPage';\r\nimport LoadingIndicator from 'flarum/common/components/LoadingIndicator';\r\nimport Placeholder from 'flarum/common/components/Placeholder';\r\nimport Button from 'flarum/common/components/Button';\r\nimport CardItem from './components/CardItem';\r\nimport ListItem from './components/ListItem';\r\n\r\napp.initializers.add('dem13n/discussion/cards', () => {\r\n\r\n extend(DiscussionListState.prototype, 'requestParams', function (params) {\r\n if (app.current.matches(IndexPage)) {\r\n params.include.push(['firstPost', 'posts', 'posts.user']);\r\n }\r\n });\r\n\r\n override(DiscussionList.prototype, 'view', function (original) {\r\n const settings = JSON.parse(app.forum.attribute('dem13nDiscussionCards'));\r\n const state = this.attrs.state;\r\n const params = state.getParams();\r\n let loading;\r\n if (state.isInitialLoading() || state.isLoadingNext()) {\r\n loading = ;\r\n } else if (state.hasNext()) {\r\n loading = Button.component(\r\n {\r\n className: 'Button',\r\n onclick: state.loadNext.bind(state),\r\n },\r\n app.translator.trans('core.forum.discussion_list.load_more_button')\r\n );\r\n }\r\n if (state.isEmpty()) {\r\n const text = app.translator.trans('core.forum.discussion_list.empty_text');\r\n return
{m(Placeholder, {text})}
;\r\n }\r\n if (app.current.matches(IndexPage) && ((settings.allowedTags.length && settings.allowedTags.includes(params.tags)) || (!params.tags && settings.onIndexPage === 1))) {\r\n return (\r\n
\r\n
\r\n {state.getPages().map((pg, o) => {\r\n return pg.items.map((discussion, i) => {\r\n return (i < settings.smallCards && o === 0)\r\n ? m(CardItem, {discussion: discussion})\r\n : m(ListItem, {discussion: discussion})\r\n });\r\n })}\r\n
\r\n
{loading}
\r\n
\r\n );\r\n\r\n } else {\r\n return original();\r\n }\r\n })\r\n}, -1);\r\n\r\n\r\n// Expose compat API\r\nimport extCompat from './compat';\r\nimport {compat} from '@flarum/core/forum';\r\n\r\nObject.assign(compat, extCompat);\r\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /less/forum.less: -------------------------------------------------------------------------------- 1 | .CardsListItem { 2 | display: block; 3 | margin-bottom: 1.5rem; 4 | background: white; 5 | overflow: visible; 6 | position: relative; 7 | 8 | &.Unread { 9 | filter: grayscale(100%); 10 | } 11 | 12 | .imageLabel { 13 | position: absolute; 14 | bottom: 35px; 15 | z-index: 1; 16 | line-height: 25px; 17 | color: #fff; 18 | 19 | &.discussionReplyCount { 20 | padding-right: 36px; 21 | padding-left: 18px; 22 | left: 0; 23 | background: linear-gradient(to right, rgba(0, 0, 0, 0.7) 0%, rgba(255, 255, 255, 0) 100%); 24 | @media @phone { 25 | display: none; 26 | } 27 | } 28 | 29 | &.discussionViews { 30 | padding-right: 18px; 31 | padding-left: 36px; 32 | right: 0; 33 | background: linear-gradient(to left, rgba(0, 0, 0, 0.7) 0%, rgba(255, 255, 255, 0) 100%); 34 | } 35 | } 36 | 37 | .labelIcon { 38 | margin-right: 5px; 39 | } 40 | 41 | &.Hidden { 42 | border: 2px dashed red; 43 | } 44 | 45 | a:hover { 46 | text-decoration: none; 47 | } 48 | 49 | h2 { 50 | font-size: 1.25rem; 51 | color: #000; 52 | font-weight: 700; 53 | } 54 | 55 | .previewCardImg { 56 | height: 14rem; 57 | margin-bottom: 1rem; 58 | width: 100%; 59 | object-fit: cover; 60 | } 61 | } 62 | 63 | .cardSpacer { 64 | height: 50px; 65 | border-bottom-left-radius: 0.5rem; 66 | border-bottom-right-radius: 0.5rem; 67 | } 68 | 69 | .Replies { 70 | height: 42px; 71 | display: flex; 72 | width: 100%; 73 | position: absolute; 74 | bottom: 0; 75 | padding: 5px 15px; 76 | border-radius: inherit; 77 | 78 | @media @phone { 79 | border-radius: unset; 80 | } 81 | 82 | &:hover { 83 | background: hsl(@primary-hue, min(100%, @primary-sat), 90%); 84 | text-underline: none; 85 | } 86 | 87 | .Left { 88 | display: flex; 89 | width: 100%; 90 | } 91 | 92 | .Avatars { 93 | align-self: center; 94 | } 95 | 96 | .Avatar--mini { 97 | .Avatar--size(24px); 98 | border: 1px solid white; 99 | 100 | &:not(:first-child) { 101 | margin-left: -15px; 102 | } 103 | 104 | &:last-child { 105 | margin-right: 10px; 106 | } 107 | } 108 | 109 | .Repcount { 110 | font-size: 14px; 111 | color: #2d4453; 112 | font-weight: bold; 113 | align-self: center; 114 | } 115 | 116 | &:hover .Arrow { 117 | opacity: 1; 118 | } 119 | 120 | .Arrow { 121 | text-align: right; 122 | align-self: center; 123 | color: #3d6d8b; 124 | opacity: 0; 125 | @media @phone { 126 | opacity: 1; 127 | } 128 | 129 | } 130 | 131 | } 132 | 133 | .cardLink { 134 | display: block; 135 | height: 100%; 136 | } 137 | 138 | .cardTitle { 139 | padding: 0 1rem 0.5rem 1rem; 140 | } 141 | 142 | .previewPost { 143 | padding: 0 1rem 0 1rem; 144 | color: gray; 145 | font-size: 16px; 146 | overflow: hidden; 147 | text-overflow: ellipsis; 148 | display: -moz-box; 149 | display: -webkit-box; 150 | -moz-box-orient: vertical; 151 | -webkit-line-clamp: 3; 152 | -webkit-box-orient: vertical; 153 | line-clamp: 3; 154 | box-orient: vertical; 155 | word-break: normal; 156 | margin-bottom: 25px; 157 | margin-top: -5px; 158 | } 159 | 160 | .flexCard { 161 | display: flex; 162 | justify-content: space-between; 163 | align-items: stretch; 164 | flex-wrap: wrap; 165 | } 166 | 167 | .imgStub { 168 | background-image: url(data:image/jpg;base64,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); 169 | height: inherit; 170 | background-repeat: no-repeat; 171 | background-size: cover; 172 | } 173 | 174 | .cardBadges { 175 | position: absolute; 176 | left: 15px; 177 | top: 15px; 178 | z-index: 1; 179 | } 180 | 181 | .cardBadge { 182 | margin-right: 3px; 183 | display: inline-block; 184 | padding: 3px 6px 3px 6px; 185 | border-radius: 4px 4px 4px 4px; 186 | font-size: 11px; 187 | text-align: center; 188 | width: 28px; 189 | line-height: 16px; 190 | } 191 | 192 | .cardTags { 193 | margin: 0 15px; 194 | display: block; 195 | width: calc(~'100% - 30px'); 196 | white-space: nowrap; 197 | overflow: hidden; 198 | } 199 | 200 | .cardTag { 201 | display: inline; 202 | color: white; 203 | padding: 2px 10px 2px 10px; 204 | 205 | &:hover { 206 | filter: opacity(0.8); 207 | text-decoration: none; 208 | } 209 | 210 | &:first-child { 211 | border-bottom-left-radius: 6px; 212 | border-top-left-radius: 6px; 213 | } 214 | 215 | &:last-child { 216 | border-bottom-right-radius: 6px; 217 | border-top-right-radius: 6px; 218 | } 219 | } 220 | 221 | #header { 222 | z-index: 1011; 223 | } 224 | 225 | .Card, .List { 226 | .wrapImg { 227 | background-color: #EDEEF0; 228 | position: relative; 229 | height: 14rem; 230 | 231 | .cardFoot { 232 | position: absolute; 233 | bottom: 5px; 234 | right: 18px; 235 | left: 18px; 236 | color: white; 237 | z-index: 1; 238 | 239 | .Author { 240 | display: inline; 241 | } 242 | 243 | .Date { 244 | display: inline; 245 | float: right; 246 | 247 | } 248 | } 249 | 250 | &.After:after { 251 | display: block; 252 | content: ""; 253 | position: absolute; 254 | width: 100%; 255 | height: 30px; 256 | bottom: 0; 257 | background-color: #000; 258 | opacity: .3; 259 | transition: 1s; 260 | -webkit-transition: 1s; 261 | } 262 | } 263 | } 264 | 265 | .List .wrapImg { 266 | height: 10rem; 267 | } 268 | 269 | @media @phone { 270 | 271 | .flexBox { 272 | flex-direction: column-reverse; 273 | } 274 | 275 | .cardGrid { 276 | .colSpan { 277 | grid-column-start: span 3; 278 | grid-column-end: span 3; 279 | } 280 | 281 | .colSpan-2 { 282 | grid-column-start: span 3; 283 | grid-column-end: span 3; 284 | } 285 | } 286 | 287 | .flexCard { 288 | background: @control-bg; 289 | } 290 | 291 | .CardsListItem { 292 | margin-bottom: 15px; 293 | border-bottom: 1px solid fade(@primary-color, 15%); 294 | 295 | .previewCardImg, .wrapImg { 296 | height: 14rem; 297 | } 298 | 299 | &:last-child { 300 | margin-bottom: 0; 301 | } 302 | 303 | .wrapImg { 304 | margin-bottom: 15px; 305 | } 306 | } 307 | 308 | } 309 | 310 | .CardsListItem { 311 | &.Card { 312 | @media @desktop-up { 313 | width: @desktop-card-width; 314 | } 315 | @media @tablet { 316 | width: @tablet-card-width; 317 | } 318 | @media @phone { 319 | width: 100%; 320 | } 321 | } 322 | 323 | &.List { 324 | width: 100%; 325 | } 326 | } 327 | 328 | @media @tablet-up { 329 | 330 | .List .cardSpacer { 331 | display: none; 332 | } 333 | 334 | .wrapImg { 335 | overflow: hidden; 336 | width: 100%; 337 | width: -webkit-fill-available; 338 | width: -moz-available; 339 | width: fill-available; 340 | 341 | img, .imgStub { 342 | transition: 1s; 343 | -webkit-transition: 1s; 344 | } 345 | } 346 | 347 | .flexBox { 348 | flex-direction: column; 349 | } 350 | 351 | .Card { 352 | 353 | .wrapImg { 354 | position: relative; 355 | display: inline-block; 356 | margin-bottom: 10px; 357 | border-top-left-radius: 0.5rem; 358 | border-top-right-radius: 0.5rem; 359 | } 360 | } 361 | 362 | .List { 363 | .wrapImg { 364 | display: block; 365 | border-top-left-radius: 0.5rem; 366 | border-bottom-left-radius: 0.5rem; 367 | position: relative; 368 | } 369 | 370 | h2.title { 371 | font-size: 19px; 372 | margin: 10px 0 0 0; 373 | } 374 | 375 | .cardTags { 376 | margin: 5px 15px 15px; 377 | display: block; 378 | width: calc(~'100% - 30px'); 379 | white-space: nowrap; 380 | overflow: hidden; 381 | } 382 | 383 | .previewPost { 384 | margin-bottom: 0; 385 | -webkit-line-clamp: 2; 386 | line-clamp: 2; 387 | } 388 | 389 | .previewCardImg { 390 | height: inherit; 391 | margin-bottom: 0; 392 | } 393 | } 394 | 395 | .CardsListItem { 396 | position: relative; 397 | border-radius: 0.5rem; 398 | -webkit-box-shadow: 0 6px 18px rgba(14, 21, 47, 0.1), 399 | 0 -2px 6px rgba(14, 21, 47, 0.02); 400 | box-shadow: 0 6px 18px rgba(14, 21, 47, 0.1), 401 | 0 -2px 6px rgba(14, 21, 47, 0.02); 402 | 403 | &:hover { 404 | background: hsl(@primary-hue, min(100%, @primary-sat), 98%); 405 | z-index: 1010; 406 | 407 | .wrapImg:after { 408 | opacity: .6; 409 | } 410 | 411 | -webkit-box-shadow: 0 6px 18px rgba(14, 21, 47, 0.2), 412 | 0 -2px 6px rgba(14, 21, 47, 0.02); 413 | box-shadow: 0 6px 18px rgba(14, 21, 47, 0.2), 414 | 0 -2px 6px rgba(14, 21, 47, 0.02); 415 | 416 | & .wrapImg { 417 | img, .imgStub { 418 | display: block; 419 | transform: scale(1.1); 420 | } 421 | } 422 | } 423 | 424 | &:hover .DiscussionListItem-controls, 425 | .DiscussionListItem-controls.open { 426 | opacity: 1; 427 | } 428 | 429 | .DiscussionListItem-controls.open { 430 | z-index: 3; 431 | } 432 | } 433 | } 434 | 435 | .Relative { 436 | position: relative; 437 | } 438 | 439 | .cardGrid { 440 | display: grid; 441 | grid-template-rows: repeat(3, minmax(0, 1fr)); 442 | grid-template-columns: repeat(3, minmax(0, 1fr)); 443 | grid-gap: 0; 444 | gap: 0; 445 | border-top-left-radius: 0.5rem; 446 | border-bottom-left-radius: 0.5rem; 447 | } 448 | 449 | .flexBox { 450 | display: flex; 451 | } 452 | 453 | .rowSpan { 454 | grid-row-start: span 1; 455 | grid-row-end: span 1; 456 | } 457 | 458 | .rowSpan-2 { 459 | grid-row-start: span 2; 460 | grid-row-end: span 2; 461 | } 462 | 463 | .rowSpan-3 { 464 | grid-row-start: span 3; 465 | grid-row-end: span 3; 466 | } 467 | 468 | .colSpan { 469 | grid-column-start: span 1; 470 | grid-column-end: span 1; 471 | } 472 | 473 | .colSpan-2 { 474 | grid-column-start: span 2; 475 | grid-column-end: span 2; 476 | } 477 | 478 | .colSpan-3 { 479 | grid-column-start: span 3; 480 | grid-column-end: span 3; 481 | } 482 | 483 | body { 484 | & when (@config-dark-mode =true) { 485 | 486 | @muted-color: hsl(@secondary-hue, min(15%, @secondary-sat), 60%); 487 | 488 | .previewPost { 489 | color: hsl(@secondary-hue, min(15%, @secondary-sat), 70%); 490 | } 491 | 492 | .Replies { 493 | &:hover { 494 | background: hsl(@primary-hue, min(20%, @primary-sat), 30%); 495 | } 496 | 497 | .Repcount, .Arrow { 498 | color: @muted-color; 499 | } 500 | 501 | .Avatar--mini { 502 | border: 1px solid black !important; 503 | } 504 | } 505 | 506 | .CardsListItem { 507 | background: hsl(@secondary-hue, min(20%, @secondary-sat), 14%); 508 | 509 | h2 { 510 | color: @muted-color; 511 | } 512 | } 513 | 514 | @media @phone { 515 | .flexCard { 516 | background: hsl(@secondary-hue, min(30%, @secondary-sat), 25%); 517 | } 518 | 519 | .CardsListItem { 520 | border-bottom: none; 521 | } 522 | } 523 | 524 | @media @tablet-up { 525 | .CardsListItem:hover { 526 | background: hsl(@secondary-hue, min(20%, @secondary-sat), 17%); 527 | } 528 | } 529 | } 530 | } 531 | --------------------------------------------------------------------------------