Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
github-classroom[bot] authored Sep 23, 2024
0 parents commit a0dce61
Show file tree
Hide file tree
Showing 182 changed files with 11,664 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "nodebb"
}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.css
npm-debug.log
sftp-config.json
*.sublime-project
*.sublime-workspace
.idea
.vscode
node_modules/
5 changes: 5 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.css
npm-debug.log
sftp-config.json
*.sublime-project
*.sublime-workspace
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Harmony theme for NodeBB
====================

The Harmony theme is the default theme for NodeBB for versions spanning v3.0.0 onwards.

## Issues

Issues are tracked in [the main project issue tracker](https://github.com/NodeBB/NodeBB/issues?q=is%3Aopen+is%3Aissue+label%3Athemes).

## Screenshots

### Categories
<img height="450" src="screenshots/categories.png">

### Recent
<img height="450" src="screenshots/recent.png">

### Topic
<img height="450" src="screenshots/topic.png">
1 change: 1 addition & 0 deletions languages/harmony.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
29 changes: 29 additions & 0 deletions lib/controllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

const Controllers = module.exports;

const accountHelpers = require.main.require('./src/controllers/accounts/helpers');
const helpers = require.main.require('./src/controllers/helpers');

Controllers.renderAdminPage = (req, res) => {
res.render('admin/plugins/harmony', {
title: '[[themes/harmony:theme-name]]',
});
};

Controllers.renderThemeSettings = async (req, res, next) => {
const userData = await accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, req.query);
if (!userData) {
return next();
}
const lib = require('../library');
userData.theme = await lib.loadThemeConfig(userData.uid);

userData.title = '[[themes/harmony:settings.title]]';
userData.breadcrumbs = helpers.buildBreadcrumbs([
{ text: userData.username, url: `/user/${userData.userslug}` },
{ text: '[[themes/harmony:settings.title]]' },
]);

res.render('account/theme', userData);
};
190 changes: 190 additions & 0 deletions library.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
'use strict';

const nconf = require.main.require('nconf');
const meta = require.main.require('./src/meta');
const _ = require.main.require('lodash');
const user = require.main.require('./src/user');

const controllers = require('./lib/controllers');

const library = module.exports;

const defaults = {
enableQuickReply: 'on',
enableBreadcrumbs: 'on',
centerHeaderElements: 'off',
mobileTopicTeasers: 'off',
stickyToolbar: 'on',
autohideBottombar: 'on',
openSidebars: 'off',
chatModals: 'off',
};

library.init = async function (params) {
const { router, middleware } = params;
const routeHelpers = require.main.require('./src/routes/helpers');

routeHelpers.setupAdminPageRoute(router, '/admin/plugins/harmony', [], controllers.renderAdminPage);

routeHelpers.setupPageRoute(router, '/user/:userslug/theme', [
middleware.exposeUid,
middleware.ensureLoggedIn,
middleware.canViewUsers,
middleware.checkAccountPermissions,
], controllers.renderThemeSettings);

if (nconf.get('isPrimary') && process.env.NODE_ENV === 'production') {
setTimeout(buildSkins, 0);
}
};

async function buildSkins() {
try {
const plugins = require.main.require('./src/plugins');
await plugins.prepareForBuild(['client side styles']);
for (const skin of meta.css.supportedSkins) {
// eslint-disable-next-line no-await-in-loop
await meta.css.buildBundle(`client-${skin}`, true);
}
require.main.require('./src/meta/minifier').killAll();
} catch (err) {
console.error(err.stack);
}
}

library.addAdminNavigation = async function (header) {
header.plugins.push({
route: '/plugins/harmony',
icon: 'fa-paint-brush',
name: '[[themes/harmony:theme-name]]',
});
return header;
};

library.addProfileItem = async (data) => {
data.links.push({
id: 'theme',
route: 'theme',
icon: 'fa-paint-brush',
name: '[[themes/harmony:settings.title]]',
visibility: {
self: true,
other: false,
moderator: false,
globalMod: false,
admin: false,
},
});

return data;
};

library.defineWidgetAreas = async function (areas) {
const locations = ['header', 'sidebar', 'footer'];
const templates = [
'categories.tpl', 'category.tpl', 'topic.tpl', 'users.tpl',
'unread.tpl', 'recent.tpl', 'popular.tpl', 'top.tpl', 'tags.tpl', 'tag.tpl',
'login.tpl', 'register.tpl',
];
function capitalizeFirst(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
templates.forEach((template) => {
locations.forEach((location) => {
areas.push({
name: `${capitalizeFirst(template.split('.')[0])} ${capitalizeFirst(location)}`,
template: template,
location: location,
});
});
});

areas = areas.concat([
{
name: 'Main post header',
template: 'topic.tpl',
location: 'mainpost-header',
},
{
name: 'Main post footer',
template: 'topic.tpl',
location: 'mainpost-footer',
},
{
name: 'Sidebar Footer',
template: 'global',
location: 'sidebar-footer',
},
{
name: 'Brand Header',
template: 'global',
location: 'brand-header',
},
{
name: 'About me (before)',
template: 'account/profile.tpl',
location: 'profile-aboutme-before',
},
{
name: 'About me (after)',
template: 'account/profile.tpl',
location: 'profile-aboutme-after',
},
]);

return areas;
};

library.loadThemeConfig = async function (uid) {
const [themeConfig, userConfig] = await Promise.all([
meta.settings.get('harmony'),
user.getSettings(uid),
]);

const config = { ...defaults, ...themeConfig, ...(_.pick(userConfig, Object.keys(defaults))) };
config.enableQuickReply = config.enableQuickReply === 'on';
config.enableBreadcrumbs = config.enableBreadcrumbs === 'on';
config.centerHeaderElements = config.centerHeaderElements === 'on';
config.mobileTopicTeasers = config.mobileTopicTeasers === 'on';
config.stickyToolbar = config.stickyToolbar === 'on';
config.autohideBottombar = config.autohideBottombar === 'on';
config.openSidebars = config.openSidebars === 'on';
config.chatModals = config.chatModals === 'on';
return config;
};

library.getThemeConfig = async function (config) {
config.theme = await library.loadThemeConfig(config.uid);
config.openDraftsOnPageLoad = false;
return config;
};

library.getAdminSettings = async function (hookData) {
if (hookData.plugin === 'harmony') {
hookData.values = {
...defaults,
...hookData.values,
};
}
return hookData;
};

library.saveUserSettings = async function (hookData) {
Object.keys(defaults).forEach((key) => {
if (hookData.data.hasOwnProperty(key)) {
hookData.settings[key] = hookData.data[key] || undefined;
}
});
return hookData;
};

library.filterMiddlewareRenderHeader = async function (hookData) {
hookData.templateData.bootswatchSkinOptions = await meta.css.getSkinSwitcherOptions(hookData.req.uid);
return hookData;
};

library.filterTeasersConfigureStripTags = function (hookData) {
// teasers have a stretched-link to go to last post, the anchors in them are not clickable
hookData.tags.push('a');
return hookData;
};
Loading

0 comments on commit a0dce61

Please sign in to comment.