nodebb-plugin-recent-cards-2 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +22 -0
- package/LICENSE +8 -0
- package/README.md +78 -0
- package/eslint.config.mjs +12 -0
- package/library.js +340 -0
- package/package.json +37 -0
- package/plugin.json +42 -0
- package/static/external/bootstrap-grid.css +14 -0
- package/static/lib/admin.js +13 -0
- package/static/lib/external.js +33 -0
- package/static/lib/main.js +340 -0
- package/static/slick/slick-theme.css +113 -0
- package/static/slick/slick.css +118 -0
- package/static/slick/slick.min.js +1 -0
- package/static/style.scss +130 -0
- package/static/templates/admin/plugins/nodebb-plugin-recent-cards/tests/external.tpl +23 -0
- package/static/templates/admin/plugins/nodebb-plugin-recent-cards/widget.tpl +60 -0
- package/static/templates/admin/plugins/recentcards.tpl +32 -0
- package/static/templates/partials/nodebb-plugin-recent-cards/external/style.tpl +307 -0
- package/static/templates/partials/nodebb-plugin-recent-cards/header.tpl +72 -0
package/.gitattributes
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Auto detect text files and perform LF normalization
|
|
2
|
+
* text=auto
|
|
3
|
+
|
|
4
|
+
# Custom for Visual Studio
|
|
5
|
+
*.cs diff=csharp
|
|
6
|
+
*.sln merge=union
|
|
7
|
+
*.csproj merge=union
|
|
8
|
+
*.vbproj merge=union
|
|
9
|
+
*.fsproj merge=union
|
|
10
|
+
*.dbproj merge=union
|
|
11
|
+
|
|
12
|
+
# Standard to msysgit
|
|
13
|
+
*.doc diff=astextplain
|
|
14
|
+
*.DOC diff=astextplain
|
|
15
|
+
*.docx diff=astextplain
|
|
16
|
+
*.DOCX diff=astextplain
|
|
17
|
+
*.dot diff=astextplain
|
|
18
|
+
*.DOT diff=astextplain
|
|
19
|
+
*.pdf diff=astextplain
|
|
20
|
+
*.PDF diff=astextplain
|
|
21
|
+
*.rtf diff=astextplain
|
|
22
|
+
*.RTF diff=astextplain
|
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Copyright (c) 2013-2014, psychobunny <psycho.bunny@hotmail.com>
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
5
|
+
|
|
6
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
7
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Recent Cards plugin for NodeBB's Persona Theme
|
|
2
|
+
|
|
3
|
+
This is a plugin that creates a new widget that can be placed on various widget areas. It's inspired by the previous default theme, Lavender, which used Modern UI styling for the category layout.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
Install via one-click activation in the Admin Control Panel or run the following command:
|
|
9
|
+
|
|
10
|
+
npm i nodebb-plugin-recent-cards
|
|
11
|
+
|
|
12
|
+
Then head over to Admin -> Extend -> Widgets and place the widget. Additional settings can be found at Admin -> Plugins -> Recent Cards and under the individual widget settings.
|
|
13
|
+
|
|
14
|
+
## Screenshot
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
# Standalone installation for external websites (Advanced)
|
|
19
|
+
|
|
20
|
+
Use this plugin on any external non-nodebb site (ex. Wordpress, etc) to show recent topics from your NodeBB install.
|
|
21
|
+
|
|
22
|
+
### Header Scripts + Styles
|
|
23
|
+
|
|
24
|
+
Place these in the `header` section of your external site, and replace all instances of `{forumURL}` to your forum's URL:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
<script src="{forumURL}/plugins/nodebb-plugin-recent-cards/static/bxslider/jquery.bxslider.min.js"></script>
|
|
28
|
+
<script>
|
|
29
|
+
window.path_to_nodebb = '{forumURL}';
|
|
30
|
+
</script>
|
|
31
|
+
<script src="{forumURL}/plugins/nodebb-plugin-recent-cards/static/lib/external.js"></script>
|
|
32
|
+
<link rel="stylesheet" type="text/css" href="{forumURL}/plugins/nodebb-plugin-recent-cards/render/style.css" />
|
|
33
|
+
<link rel="stylesheet" type="text/css" href="{forumURL}/plugins/nodebb-plugin-recent-cards/static/bxslider/jquery.bxslider.css" />
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If your external site doesn't have jQuery included, you will have include it above the previous lines. Get the latest jQuery at https://code.jquery.com/
|
|
37
|
+
|
|
38
|
+
You should also (optionally) require the jQuery Timeago library in order to display human-readable timestamps:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.6.1/jquery.timeago.min.js"></script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If your external site doesn't have Bootstrap included, you will have to include this line as well in your `header`, which is the bare minimum (grid + responsive utilities) required for this plugin:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
<link rel="stylesheet" type="text/css" href="{forumURL}/plugins/nodebb-plugin-recent-cards/static/external/bootstrap-grid.css" />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Similarly, if your external site does not use FontAwesome, then you will have to include this line as well in order to display category icons:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
Finally, if you need to include the default Persona font to match your external site's recent cards with your forum's, then include this:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
<link rel="prefetch stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### Body Content
|
|
65
|
+
|
|
66
|
+
Place the following code wherever you'd like recent cards to be displayed:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
<div id="nodebb-plugin-recent-cards"></div>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Configure ACAO in NodeBB
|
|
73
|
+
|
|
74
|
+
Under Settings -> Advanced in the NodeBB control panel, add the external site's URL to `Access-Control-Allow-Origin`
|
|
75
|
+
|
|
76
|
+
### Stuck?
|
|
77
|
+
|
|
78
|
+
No problem! Visit https://yourforum.com/admin/plugins/nodebb-plugin-recent-cards/tests/external, which will render the standalone version of the plugin tailored for your website. Keep in mind that this includes all extra scripts and styling that you may not necessarily need if you already have Bootstrap, jQuery, etc. on your external site.
|
package/library.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/* eslint-disable no-await-in-loop */
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const nconf = require.main.require('nconf');
|
|
6
|
+
const _ = require.main.require('lodash');
|
|
7
|
+
const validator = require.main.require('validator');
|
|
8
|
+
const db = require.main.require('./src/database');
|
|
9
|
+
const topics = require.main.require('./src/topics');
|
|
10
|
+
const settings = require.main.require('./src/settings');
|
|
11
|
+
const groups = require.main.require('./src/groups');
|
|
12
|
+
const user = require.main.require('./src/user');
|
|
13
|
+
|
|
14
|
+
const defaultSettings = {
|
|
15
|
+
enableCarousel: 1,
|
|
16
|
+
enableCarouselPagination: 0,
|
|
17
|
+
minSlides: 1,
|
|
18
|
+
maxSlides: 4,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const plugin = module.exports;
|
|
22
|
+
let app;
|
|
23
|
+
|
|
24
|
+
plugin.init = async function (params) {
|
|
25
|
+
app = params.app;
|
|
26
|
+
const { router } = params;
|
|
27
|
+
const routeHelpers = require.main.require('./src/routes/helpers');
|
|
28
|
+
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/recentcards', renderAdmin);
|
|
29
|
+
|
|
30
|
+
router.get('/plugins/nodebb-plugin-recent-cards/render', renderExternal);
|
|
31
|
+
router.get('/plugins/nodebb-plugin-recent-cards/render/style.css', renderExternalStyle);
|
|
32
|
+
router.get('/plugins/nodebb-plugin-recent-cards/filter', renderFiltered);
|
|
33
|
+
router.get('/admin/plugins/nodebb-plugin-recent-cards/tests/external', testRenderExternal);
|
|
34
|
+
|
|
35
|
+
plugin.settings = new settings('recentcards', '1.0.0', defaultSettings);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
plugin.addAdminNavigation = async function (header) {
|
|
39
|
+
header.plugins.push({
|
|
40
|
+
route: '/plugins/recentcards',
|
|
41
|
+
icon: 'fa-tint',
|
|
42
|
+
name: 'Recent Cards',
|
|
43
|
+
});
|
|
44
|
+
return header;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
plugin.defineWidgets = async function (widgets) {
|
|
48
|
+
const groupNames = await db.getSortedSetRevRange('groups:visible:createtime', 0, -1);
|
|
49
|
+
let groupsData = await groups.getGroupsData(groupNames);
|
|
50
|
+
groupsData = groupsData.filter(Boolean);
|
|
51
|
+
groupsData.forEach((group) => {
|
|
52
|
+
group.name = validator.escape(String(group.name));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const html = await app.renderAsync('admin/plugins/nodebb-plugin-recent-cards/widget', {
|
|
56
|
+
groups: groupsData,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
widgets.push({
|
|
60
|
+
widget: 'recentCards',
|
|
61
|
+
name: 'Recent Cards',
|
|
62
|
+
description: 'Recent topics carousel',
|
|
63
|
+
content: html,
|
|
64
|
+
});
|
|
65
|
+
return widgets;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
plugin.getConfig = async function (config) {
|
|
69
|
+
config.recentCards = {
|
|
70
|
+
title: plugin.settings.get('title'),
|
|
71
|
+
opacity: plugin.settings.get('opacity'),
|
|
72
|
+
textShadow: plugin.settings.get('shadow'),
|
|
73
|
+
enableCarousel: plugin.settings.get('enableCarousel'),
|
|
74
|
+
enableCarouselPagination: plugin.settings.get('enableCarouselPagination'),
|
|
75
|
+
minSlides: plugin.settings.get('minSlides'),
|
|
76
|
+
maxSlides: plugin.settings.get('maxSlides'),
|
|
77
|
+
};
|
|
78
|
+
return config;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
plugin.renderWidget = async function (widget) {
|
|
82
|
+
if (!isVisibleInCategory(widget)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const topics = await getTopics(widget);
|
|
86
|
+
|
|
87
|
+
const categoryMap = {};
|
|
88
|
+
topics.forEach((t) => {
|
|
89
|
+
if (t && t.category && !categoryMap[t.category.cid]) {
|
|
90
|
+
categoryMap[t.category.cid] = {
|
|
91
|
+
cid: t.category.cid,
|
|
92
|
+
name: t.category.name,
|
|
93
|
+
icon: t.category.icon,
|
|
94
|
+
bgColor: t.category.bgColor,
|
|
95
|
+
color: t.category.color,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
const categories = Object.values(categoryMap);
|
|
100
|
+
|
|
101
|
+
const widgetConfig = {
|
|
102
|
+
sort: widget.data.sort || 'recent',
|
|
103
|
+
teaserPost: widget.data.teaserPost || 'first',
|
|
104
|
+
teaserParseType: widget.data.teaserParseType || 'default',
|
|
105
|
+
thumbnailStyle: widget.data.thumbnailStyle || 'background',
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
widget.html = await app.renderAsync('partials/nodebb-plugin-recent-cards/header', {
|
|
109
|
+
topics: topics,
|
|
110
|
+
config: widget.templateData.config,
|
|
111
|
+
title: widget.data.title || '',
|
|
112
|
+
carouselMode: plugin.settings.get('enableCarousel'),
|
|
113
|
+
categories: JSON.stringify(categories).replace(/</g, '\\u003c'),
|
|
114
|
+
widgetConfig: JSON.stringify(widgetConfig).replace(/</g, '\\u003c'),
|
|
115
|
+
});
|
|
116
|
+
return widget;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
function getIdsArray(data, field) {
|
|
120
|
+
const ids = String(data[field] || '');
|
|
121
|
+
return ids.split(',').map(c => c.trim()).filter(Boolean);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function isVisibleInCategory(widget) {
|
|
125
|
+
const cids = getIdsArray(widget.data, 'cid');
|
|
126
|
+
return !(
|
|
127
|
+
cids.length &&
|
|
128
|
+
(widget.templateData.template.category || widget.templateData.template.topic) &&
|
|
129
|
+
!cids.includes(String(widget.templateData.cid))
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function getTopics(widget) {
|
|
134
|
+
const teaserPost = widget.data.teaserPost || 'first';
|
|
135
|
+
const teaserParseType = widget.data.teaserParseType || 'default';
|
|
136
|
+
const getTopicsOptions = {
|
|
137
|
+
uid: widget.uid,
|
|
138
|
+
teaserPost,
|
|
139
|
+
teaserParseType,
|
|
140
|
+
thumbsOnly: true,
|
|
141
|
+
};
|
|
142
|
+
async function getTopicsFromSet(set) {
|
|
143
|
+
let start = 0;
|
|
144
|
+
const topicsData = [];
|
|
145
|
+
|
|
146
|
+
do {
|
|
147
|
+
let tids = await db.getSortedSetRevRangeByScore(set, start, 20, Date.now(), '-inf');
|
|
148
|
+
if (!tids.length) {
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
tids = await topics.filterNotIgnoredTids(tids, widget.uid);
|
|
153
|
+
let nextTopics = await topics.getTopics(tids, getTopicsOptions);
|
|
154
|
+
|
|
155
|
+
nextTopics = await user.blocks.filter(widget.uid, nextTopics);
|
|
156
|
+
topicsData.push(...nextTopics);
|
|
157
|
+
start += 20;
|
|
158
|
+
} while (topicsData.length < 20);
|
|
159
|
+
return { topics: topicsData.slice(0, 20) };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let topicsData = {
|
|
163
|
+
topics: [],
|
|
164
|
+
};
|
|
165
|
+
let filterCids = getIdsArray(widget.data, 'topicsFromCid');
|
|
166
|
+
if (!filterCids.length && widget.templateData.cid) {
|
|
167
|
+
filterCids = [String(widget.templateData.cid)];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
widget.data.sort = widget.data.sort || 'recent';
|
|
171
|
+
let fromGroups = widget.data.fromGroups || [];
|
|
172
|
+
if (fromGroups && !Array.isArray(fromGroups)) {
|
|
173
|
+
fromGroups = [fromGroups];
|
|
174
|
+
}
|
|
175
|
+
// hard coded to show these topic tids only
|
|
176
|
+
const topicsTids = getIdsArray(widget.data, 'topicsTids');
|
|
177
|
+
if (topicsTids.length) {
|
|
178
|
+
topicsData.topics = await topics.getTopics(topicsTids, getTopicsOptions);
|
|
179
|
+
} else if (fromGroups.length) {
|
|
180
|
+
const uids = _.uniq(_.flatten(await groups.getMembersOfGroups(fromGroups)));
|
|
181
|
+
const sets = uids.map((uid) => {
|
|
182
|
+
if (filterCids.length) {
|
|
183
|
+
return filterCids.map(cid => `cid:${cid}:uid:${uid}:tids`);
|
|
184
|
+
}
|
|
185
|
+
return `uid:${uid}:topics`;
|
|
186
|
+
});
|
|
187
|
+
topicsData = await getTopicsFromSet(sets.flat());
|
|
188
|
+
topicsData.topics.sort((t1, t2) => {
|
|
189
|
+
if (widget.data.sort === 'recent') {
|
|
190
|
+
return t2.lastposttime - t1.lastposttime;
|
|
191
|
+
} else if (widget.data.sort === 'votes') {
|
|
192
|
+
return t2.votes - t1.votes;
|
|
193
|
+
} else if (widget.data.sort === 'posts') {
|
|
194
|
+
return t2.postcount - t1.postcount;
|
|
195
|
+
}
|
|
196
|
+
return 0;
|
|
197
|
+
});
|
|
198
|
+
} else if (filterCids.length) {
|
|
199
|
+
let searchSuffix = '';
|
|
200
|
+
if (widget.data.sort === 'recent') {
|
|
201
|
+
searchSuffix += ':lastposttime';
|
|
202
|
+
} else if (widget.data.sort === 'votes' || widget.data.sort === 'posts' || widget.data.sort === 'create') {
|
|
203
|
+
searchSuffix += `:${widget.data.sort}`;
|
|
204
|
+
}
|
|
205
|
+
topicsData = await getTopicsFromSet(
|
|
206
|
+
filterCids.map(cid => `cid:${cid}:tids${searchSuffix}`)
|
|
207
|
+
);
|
|
208
|
+
} else {
|
|
209
|
+
const map = {
|
|
210
|
+
votes: 'topics:votes',
|
|
211
|
+
posts: 'topics:posts',
|
|
212
|
+
recent: 'topics:recent',
|
|
213
|
+
create: 'topics:tid',
|
|
214
|
+
};
|
|
215
|
+
topicsData = await getTopicsFromSet(map[widget.data.sort]);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
let i = 0;
|
|
219
|
+
const cids = [];
|
|
220
|
+
let finalTopics = [];
|
|
221
|
+
|
|
222
|
+
if (!plugin.settings.get('enableCarousel')) {
|
|
223
|
+
while (finalTopics.length < 4 && i < topicsData.topics.length) {
|
|
224
|
+
const cid = String(topicsData.topics[i].cid);
|
|
225
|
+
|
|
226
|
+
if (filterCids.length || !cids.includes(cid) || topicsData.topics.length <= 4) {
|
|
227
|
+
cids.push(cid);
|
|
228
|
+
finalTopics.push(topicsData.topics[i]);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
i += 1;
|
|
232
|
+
}
|
|
233
|
+
} else {
|
|
234
|
+
finalTopics = topicsData.topics;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const thumbStyle = widget.data.thumbnailStyle || 'background';
|
|
238
|
+
finalTopics.forEach((t) => {
|
|
239
|
+
if (t) {
|
|
240
|
+
const showThumbs = t.thumbs?.length && String(t?.teaser.pid) === String(t.mainPid);
|
|
241
|
+
t.showThumbnailInBackground = showThumbs && thumbStyle === 'background';
|
|
242
|
+
t.showThumbnailInline = showThumbs && thumbStyle === 'inline';
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return finalTopics;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async function renderExternal(req, res, next) {
|
|
250
|
+
try {
|
|
251
|
+
const topicsData = await getTopics({
|
|
252
|
+
uid: req.uid,
|
|
253
|
+
data: {
|
|
254
|
+
teaserPost: 'first',
|
|
255
|
+
},
|
|
256
|
+
templateData: {},
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const categoryMap = {};
|
|
260
|
+
topicsData.forEach((t) => {
|
|
261
|
+
if (t && t.category && !categoryMap[t.category.cid]) {
|
|
262
|
+
categoryMap[t.category.cid] = {
|
|
263
|
+
cid: t.category.cid,
|
|
264
|
+
name: t.category.name,
|
|
265
|
+
icon: t.category.icon,
|
|
266
|
+
bgColor: t.category.bgColor,
|
|
267
|
+
color: t.category.color,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
res.render('partials/nodebb-plugin-recent-cards/header', {
|
|
273
|
+
topics: topicsData,
|
|
274
|
+
config: {
|
|
275
|
+
relative_path: nconf.get('url'),
|
|
276
|
+
},
|
|
277
|
+
categories: JSON.stringify(Object.values(categoryMap)).replace(/</g, '\\u003c'),
|
|
278
|
+
widgetConfig: '{}',
|
|
279
|
+
});
|
|
280
|
+
} catch (err) {
|
|
281
|
+
next(err);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async function renderFiltered(req, res, next) {
|
|
286
|
+
try {
|
|
287
|
+
const cids = String(req.query.cids || '');
|
|
288
|
+
const sort = String(req.query.sort || 'recent');
|
|
289
|
+
const teaserPost = String(req.query.teaserPost || 'first');
|
|
290
|
+
const teaserParseType = String(req.query.teaserParseType || 'default');
|
|
291
|
+
const thumbnailStyle = String(req.query.thumbnailStyle || 'background');
|
|
292
|
+
|
|
293
|
+
const allowedSorts = ['recent', 'create', 'votes', 'posts'];
|
|
294
|
+
const allowedTeasers = ['first', 'last-post'];
|
|
295
|
+
const allowedParseTypes = ['default', 'plaintext'];
|
|
296
|
+
const allowedThumbs = ['background', 'inline'];
|
|
297
|
+
|
|
298
|
+
const filteredTopics = await getTopics({
|
|
299
|
+
uid: req.uid,
|
|
300
|
+
data: {
|
|
301
|
+
topicsFromCid: cids,
|
|
302
|
+
sort: allowedSorts.includes(sort) ? sort : 'recent',
|
|
303
|
+
teaserPost: allowedTeasers.includes(teaserPost) ? teaserPost : 'first',
|
|
304
|
+
teaserParseType: allowedParseTypes.includes(teaserParseType) ? teaserParseType : 'default',
|
|
305
|
+
thumbnailStyle: allowedThumbs.includes(thumbnailStyle) ? thumbnailStyle : 'background',
|
|
306
|
+
},
|
|
307
|
+
templateData: {},
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
const html = await app.renderAsync('partials/nodebb-plugin-recent-cards/header', {
|
|
311
|
+
topics: filteredTopics,
|
|
312
|
+
config: { relative_path: nconf.get('relative_path') },
|
|
313
|
+
carouselMode: plugin.settings.get('enableCarousel'),
|
|
314
|
+
categories: '[]',
|
|
315
|
+
widgetConfig: '{}',
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
res.json({ html: html });
|
|
319
|
+
} catch (err) {
|
|
320
|
+
next(err);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function renderExternalStyle(req, res) {
|
|
325
|
+
res.render('partials/nodebb-plugin-recent-cards/external/style', {
|
|
326
|
+
forumURL: nconf.get('url'),
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function testRenderExternal(req, res) {
|
|
331
|
+
res.render('admin/plugins/nodebb-plugin-recent-cards/tests/external', {
|
|
332
|
+
forumURL: nconf.get('url'),
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
async function renderAdmin(req, res) {
|
|
337
|
+
res.render('admin/plugins/recentcards', {
|
|
338
|
+
title: 'Recent Cards',
|
|
339
|
+
});
|
|
340
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nodebb-plugin-recent-cards-2",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Add lavender-style cards of recent topics to Persona's category homepage",
|
|
5
|
+
"main": "library.js",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/psychobunny/nodebb-plugin-recent-cards"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"lint": "eslint ."
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"nodebb",
|
|
15
|
+
"plugin",
|
|
16
|
+
"recent",
|
|
17
|
+
"cards",
|
|
18
|
+
"persona"
|
|
19
|
+
],
|
|
20
|
+
"author": {
|
|
21
|
+
"name": "psychobunny",
|
|
22
|
+
"email": "psycho.bunny@hotmail.com"
|
|
23
|
+
},
|
|
24
|
+
"license": "BSD-2-Clause",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/psychobunny/nodebb-plugin-recent-cards/issues"
|
|
27
|
+
},
|
|
28
|
+
"readmeFilename": "README.md",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"eslint": "^9.x",
|
|
31
|
+
"eslint-config-nodebb": "1.1.11",
|
|
32
|
+
"eslint-plugin-import": "2.32.0"
|
|
33
|
+
},
|
|
34
|
+
"nbbpm": {
|
|
35
|
+
"compatibility": "^4.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/plugin.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "nodebb-plugin-recent-cards",
|
|
3
|
+
"name": "Recent Cards plugin for NodeBB's Persona Theme",
|
|
4
|
+
"description": "Add lavender-style cards of recent topics to Persona's category homepage",
|
|
5
|
+
"url": "https://github.com/NodeBB/nodebb-plugin-recent-cards",
|
|
6
|
+
"library": "./library.js",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"hook": "static:app.load", "method": "init"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"hook": "filter:config.get", "method": "getConfig"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"hook": "filter:admin.header.build", "method": "addAdminNavigation"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"hook": "filter:widgets.getWidgets", "method": "defineWidgets"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"hook": "filter:widget.render:recentCards", "method": "renderWidget"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"staticDirs": {
|
|
25
|
+
"static": "./static"
|
|
26
|
+
},
|
|
27
|
+
"css": [
|
|
28
|
+
"static/slick/slick.css",
|
|
29
|
+
"static/slick/slick-theme.css"
|
|
30
|
+
],
|
|
31
|
+
"scss": [
|
|
32
|
+
"static/style.scss"
|
|
33
|
+
],
|
|
34
|
+
"scripts": [
|
|
35
|
+
"static/slick/slick.min.js",
|
|
36
|
+
"static/lib/main.js"
|
|
37
|
+
],
|
|
38
|
+
"modules": {
|
|
39
|
+
"../admin/plugins/recentcards.js": "static/lib/admin.js"
|
|
40
|
+
},
|
|
41
|
+
"templates": "static/templates"
|
|
42
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
|
3
|
+
* Copyright 2011-2018 Twitter, Inc.
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*!
|
|
8
|
+
* Generated using the Bootstrap Customizer (https://getbootstrap.com/docs/3.3/customize/?id=cd87b217e33874f77fb457b6338264bb)
|
|
9
|
+
* Config saved to config.json and https://gist.github.com/cd87b217e33874f77fb457b6338264bb
|
|
10
|
+
*//*!
|
|
11
|
+
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
|
12
|
+
* Copyright 2011-2016 Twitter, Inc.
|
|
13
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
|
14
|
+
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
define('admin/plugins/recentcards', ['settings'], function (settings) {
|
|
4
|
+
const admin = {};
|
|
5
|
+
admin.init = function () {
|
|
6
|
+
settings.sync('recentcards', $('#recentcards'));
|
|
7
|
+
|
|
8
|
+
$('#save').click(function () {
|
|
9
|
+
settings.persist('recentcards', $('#recentcards'));
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
return admin;
|
|
13
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
$(document).ready(function () {
|
|
4
|
+
$.get(window.path_to_nodebb + '/plugins/nodebb-plugin-recent-cards/render', {}, function (html) {
|
|
5
|
+
html = $(html);
|
|
6
|
+
if (html.length !== 5) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
$('#nodebb-plugin-recent-cards').html($(html[2]));
|
|
11
|
+
|
|
12
|
+
var ajaxifyData = $(html[4]);
|
|
13
|
+
|
|
14
|
+
if (ajaxifyData.length) {
|
|
15
|
+
ajaxifyData = JSON.parse(ajaxifyData.text());
|
|
16
|
+
|
|
17
|
+
if (ajaxifyData.recentCards.enableCarousel) {
|
|
18
|
+
$('#nodebb-plugin-recent-cards .recent-cards').bxSlider({
|
|
19
|
+
slideWidth: 292,
|
|
20
|
+
minSlides: 1,
|
|
21
|
+
maxSlides: 4,
|
|
22
|
+
pager: ajaxifyData.recentCards.enableCarouselPagination ? true : false,
|
|
23
|
+
});
|
|
24
|
+
} else {
|
|
25
|
+
$('#nodebb-plugin-recent-cards .recent-cards').removeClass('carousel-mode');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if ($.timeago) {
|
|
29
|
+
$('#nodebb-plugin-recent-cards .timeago').not('[datetime]').timeago();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|