diff --git a/.eslintrc b/.eslintrc
index e15e70d..293600c 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,18 +1,36 @@
{
- "extends": "eslint-config-airbnb",
- "rules": {
- "import/no-unresolved": "off",
- "import/no-extraneous-dependencies": "off",
- "react/jsx-filename-extension": ["error", { "extensions": [".js", ".jsx"] }],
- "react/react-in-jsx-scope": "off",
- "react/prop-types": "off",
- "import/extensions": ["error", "never"]
- },
- "env": {
- "jquery": true
- },
- "globals": {
- "app": false,
- "m": false
- }
-}
+ "extends": "eslint-config-airbnb",
+ "rules": {
+ "class-methods-use-this": "off",
+ "func-names": "off",
+ "no-param-reassign": "off",
+ "import/no-unresolved": "off",
+ "import/no-extraneous-dependencies": "off",
+ "import/extensions": ["error", "never"],
+ "react/jsx-filename-extension": ["error", { "extensions": [".js"] }],
+ "react/react-in-jsx-scope": "off",
+ "react/prop-types": "off",
+ "react/sort-comp": ["error", {
+ "order": [
+ "/^constructor$/",
+ "/^init$/",
+ "/^initProps$/",
+ "static-methods",
+ "/^content$/",
+ "/^view$/",
+ "/^config$/",
+ "everything-else",
+ "/^onsubmit$/",
+ "/^onerror$/"
+ ]
+ }]
+ },
+ "env": {
+ "jquery": true,
+ "browser": true
+ },
+ "globals": {
+ "app": false,
+ "m": false
+ }
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e548ebe
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+/vendor
+composer.phar
+.DS_Store
+Thumbs.db
+bower_components
+node_modules
+*.js.old
diff --git a/bootstrap.php b/bootstrap.php
index 25f5f3e..1eb565d 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -15,5 +15,6 @@
return function (Dispatcher $events) {
$events->subscribe(Listeners\AddClientAssets::class);
$events->subscribe(Listeners\LoadSettingsFromDatabase::class);
- $events->subscribe(Listeners\AddApiAttributes::class);
+ $events->subscribe(Listeners\AddUserProfileAttributes::class);
+ $events->subscribe(Listeners\UpdateProfileInDatabase::class);
};
diff --git a/js/admin/dist/extension.js b/js/admin/dist/extension.js
index eb1c69c..9febf08 100644
--- a/js/admin/dist/extension.js
+++ b/js/admin/dist/extension.js
@@ -1,24 +1,26 @@
-System.register('davis/socialprofile/components/SocialProfileSettingsModal', ['flarum/components/SettingsModal'], function (_export) {
- 'use strict';
+'use strict';
- var SettingsModal, AnimatedTagSettingsModal;
+System.register('Davis/SocialProfile/components/SocialProfileSettingsModal', ['flarum/components/SettingsModal'], function (_export, _context) {
+ "use strict";
+
+ var SettingsModal, SocialProfileSettingsModal;
return {
setters: [function (_flarumComponentsSettingsModal) {
- SettingsModal = _flarumComponentsSettingsModal['default'];
+ SettingsModal = _flarumComponentsSettingsModal.default;
}],
execute: function () {
- AnimatedTagSettingsModal = (function (_SettingsModal) {
- babelHelpers.inherits(AnimatedTagSettingsModal, _SettingsModal);
+ SocialProfileSettingsModal = function (_SettingsModal) {
+ babelHelpers.inherits(SocialProfileSettingsModal, _SettingsModal);
- function AnimatedTagSettingsModal() {
- babelHelpers.classCallCheck(this, AnimatedTagSettingsModal);
- babelHelpers.get(Object.getPrototypeOf(AnimatedTagSettingsModal.prototype), 'constructor', this).apply(this, arguments);
+ function SocialProfileSettingsModal() {
+ babelHelpers.classCallCheck(this, SocialProfileSettingsModal);
+ return babelHelpers.possibleConstructorReturn(this, (SocialProfileSettingsModal.__proto__ || Object.getPrototypeOf(SocialProfileSettingsModal)).apply(this, arguments));
}
- babelHelpers.createClass(AnimatedTagSettingsModal, [{
+ babelHelpers.createClass(SocialProfileSettingsModal, [{
key: 'className',
value: function className() {
- return 'AnimatedTagSettingsModal Modal--small';
+ return 'SocialProfileSettingsModal Modal--small';
}
}, {
key: 'title',
@@ -28,42 +30,38 @@ System.register('davis/socialprofile/components/SocialProfileSettingsModal', ['f
}, {
key: 'form',
value: function form() {
- return [m(
+ return m(
'div',
{ className: 'Form-group' },
m(
'label',
- null,
+ { htmlFor: 'test' },
app.translator.trans('davis-socialprofile.admin.test')
),
- m('input', { type: 'text', className: 'FormControl', bidi: this.setting('davis.socialprofile.test') })
- )];
+ m('input', { name: 'test', type: 'text', className: 'FormControl', bidi: this.setting('davis.socialprofile.test') })
+ );
}
}]);
- return AnimatedTagSettingsModal;
- })(SettingsModal);
+ return SocialProfileSettingsModal;
+ }(SettingsModal);
- _export('default', AnimatedTagSettingsModal);
+ _export('default', SocialProfileSettingsModal);
}
};
});;
-System.register('davis/socialprofile/main', ['flarum/extend', 'flarum/app', 'davis/socialprofile/components/SocialProfileSettingsModal'], function (_export) {
- 'use strict';
+'use strict';
+
+System.register('Davis/SocialProfile/main', ['flarum/app'], function (_export, _context) {
+ "use strict";
- var extend, app, SocialProfileSettingsModal;
+ var app;
return {
- setters: [function (_flarumExtend) {
- extend = _flarumExtend.extend;
- }, function (_flarumApp) {
- app = _flarumApp['default'];
- }, function (_davisSocialprofileComponentsSocialProfileSettingsModal) {
- SocialProfileSettingsModal = _davisSocialprofileComponentsSocialProfileSettingsModal['default'];
+ setters: [function (_flarumApp) {
+ app = _flarumApp.default;
}],
execute: function () {
- app.initializers.add('davis-socialprofile', function (app) {
- //app.extensionSettings['davis-socialprofile'] = () => app.modal.show(new SocialProfileSettingsModal());
- });
+ app.initializers.add('Davis-SocialProfile', function () {});
}
};
});
\ No newline at end of file
diff --git a/js/admin/package.json b/js/admin/package.json
index e0cad46..2bdaf6a 100644
--- a/js/admin/package.json
+++ b/js/admin/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"devDependencies": {
- "gulp": "^3.8.11",
- "flarum-gulp": "^0.2.0"
+ "gulp": "^3.9.1",
+ "flarum-gulp": "dav-is/flarum-gulp#patch-1"
}
-}
+}
\ No newline at end of file
diff --git a/js/admin/src/components/SocialProfileSettingsModal.js b/js/admin/src/components/SocialProfileSettingsModal.js
index 19dabff..5f7e75f 100644
--- a/js/admin/src/components/SocialProfileSettingsModal.js
+++ b/js/admin/src/components/SocialProfileSettingsModal.js
@@ -1,8 +1,8 @@
import SettingsModal from 'flarum/components/SettingsModal';
-export default class AnimatedTagSettingsModal extends SettingsModal {
+export default class SocialProfileSettingsModal extends SettingsModal {
className() {
- return 'AnimatedTagSettingsModal Modal--small';
+ return 'SocialProfileSettingsModal Modal--small';
}
title() {
@@ -10,11 +10,11 @@ export default class AnimatedTagSettingsModal extends SettingsModal {
}
form() {
- return [
+ return (
-
-
+
+
- ];
+ );
}
}
diff --git a/js/admin/src/main.js b/js/admin/src/main.js
index c1898b6..41cf065 100644
--- a/js/admin/src/main.js
+++ b/js/admin/src/main.js
@@ -1,7 +1,5 @@
-import { extend } from 'flarum/extend';
import app from 'flarum/app';
-import SocialProfileSettingsModal from 'Davis/SocialProfile/components/SocialProfileSettingsModal';
-app.initializers.add('Davis-SocialProfile', app => {
- //app.extensionSettings['davis-socialprofile'] = () => app.modal.show(new SocialProfileSettingsModal());
+app.initializers.add('Davis-SocialProfile', () => {
+
});
diff --git a/js/forum/dist/extension.js b/js/forum/dist/extension.js
index b686d24..79fee1a 100644
--- a/js/forum/dist/extension.js
+++ b/js/forum/dist/extension.js
@@ -1,6 +1,129 @@
'use strict';
+System.register('Davis/SocialProfile/components/DeleteButtonModal', ['flarum/components/Modal', 'flarum/components/Button'], function (_export, _context) {
+ "use strict";
+
+ var Modal, Button, DeleteButtonModal;
+ return {
+ setters: [function (_flarumComponentsModal) {
+ Modal = _flarumComponentsModal.default;
+ }, function (_flarumComponentsButton) {
+ Button = _flarumComponentsButton.default;
+ }],
+ execute: function () {
+ DeleteButtonModal = function (_Modal) {
+ babelHelpers.inherits(DeleteButtonModal, _Modal);
+
+ function DeleteButtonModal() {
+ babelHelpers.classCallCheck(this, DeleteButtonModal);
+ return babelHelpers.possibleConstructorReturn(this, (DeleteButtonModal.__proto__ || Object.getPrototypeOf(DeleteButtonModal)).apply(this, arguments));
+ }
+
+ babelHelpers.createClass(DeleteButtonModal, [{
+ key: 'init',
+ value: function init() {
+ var _this2 = this;
+
+ babelHelpers.get(DeleteButtonModal.prototype.__proto__ || Object.getPrototypeOf(DeleteButtonModal.prototype), 'init', this).call(this);
+
+ this.buttons = [];
+ this.index = this.props.index;
+ var buttons = JSON.parse(this.props.user.data.attributes.socialButtons || '[]');
+ this.button = buttons[this.index];
+
+ buttons.forEach(function (button, index) {
+ _this2.createButtonObject(index, button);
+ });
+ }
+ }, {
+ key: 'className',
+ value: function className() {
+ return 'SocialButtonsModal Modal--small';
+ }
+ }, {
+ key: 'title',
+ value: function title() {
+ return app.translator.trans('davis-socialprofile.forum.edit.deletetitle');
+ }
+ }, {
+ key: 'content',
+ value: function content() {
+ $('.Modal-content').css('overflow', 'visible');
+ return [m('div', { className: 'Modal-body' }, [m('div', { className: 'Form' }, [m('h3', { className: 'SocialProfile-title' }, this.button.title), m('p', { className: 'SocialProfile-url' }, this.button.url), m('div', { className: 'Form-group', id: 'submit-button-group' }, [Button.component({
+ type: 'submit',
+ className: 'Button Button--primary EditSocialButtons-delete',
+ loading: this.loading,
+ children: app.translator.trans('davis-socialprofile.forum.edit.delete')
+ })])])])];
+ }
+ }, {
+ key: 'data',
+ value: function data() {
+ var buttons = [];
+
+ this.buttons.forEach(function (button, index) {
+ if (button.title() !== '') {
+ buttons[index] = {};
+ buttons[index].title = button.title();
+ buttons[index].url = button.url();
+ buttons[index].icon = button.icon();
+ buttons[index].favicon = button.favicon();
+ }
+ });
+
+ return {
+ socialButtons: JSON.stringify(buttons)
+ };
+ }
+ }, {
+ key: 'onsubmit',
+ value: function onsubmit(e) {
+ var _this3 = this;
+
+ e.preventDefault();
+
+ this.loading = true;
+ this.buttons.splice(this.index, 1);
+
+ this.props.user.save(this.data(), { errorHandler: this.onerror.bind(this) }).then(this.hide.bind(this)).then($('#app').trigger('refreshSocialButtons', [this.data().socialButtons])).catch(function () {
+ _this3.loading = false;
+ m.redraw();
+ });
+ }
+ }, {
+ key: 'createButtonObject',
+ value: function createButtonObject(key) {
+ var button = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
+
+ if (button == null) {
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop('none');
+ this.buttons[key].title = m.prop('');
+ this.buttons[key].url = m.prop('');
+ this.buttons[key].icon = m.prop('globe');
+ } else {
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop(button.favicon);
+ this.buttons[key].title = m.prop(button.title);
+ this.buttons[key].url = m.prop(button.url);
+ this.buttons[key].icon = m.prop(button.icon);
+ }
+ }
+ }]);
+ return DeleteButtonModal;
+ }(Modal);
+
+ _export('default', DeleteButtonModal);
+ }
+ };
+});;
+'use strict';
+
System.register('Davis/SocialProfile/components/IconSelectorComponent', ['flarum/components/Dropdown', 'flarum/utils/ItemList', 'flarum/helpers/icon'], function (_export, _context) {
+ "use strict";
+
var Dropdown, ItemList, icon, IconSelectorComponent;
return {
setters: [function (_flarumComponentsDropdown) {
@@ -16,16 +139,16 @@ System.register('Davis/SocialProfile/components/IconSelectorComponent', ['flarum
function IconSelectorComponent() {
babelHelpers.classCallCheck(this, IconSelectorComponent);
- return babelHelpers.possibleConstructorReturn(this, Object.getPrototypeOf(IconSelectorComponent).apply(this, arguments));
+ return babelHelpers.possibleConstructorReturn(this, (IconSelectorComponent.__proto__ || Object.getPrototypeOf(IconSelectorComponent)).apply(this, arguments));
}
babelHelpers.createClass(IconSelectorComponent, [{
key: 'init',
value: function init() {
- babelHelpers.get(Object.getPrototypeOf(IconSelectorComponent.prototype), 'init', this).call(this);
+ babelHelpers.get(IconSelectorComponent.prototype.__proto__ || Object.getPrototypeOf(IconSelectorComponent.prototype), 'init', this).call(this);
this.icons = {
- 'social': ["fa-globe", 'fa-amazon', 'fa-angellist', 'fa-apple', 'fa-behance', 'fa-bitbucket', 'fa-codepen', 'fa-connectdevelop', 'fa-dashcube', 'fa-delicious', 'fa-deviantart', 'fa-digg', 'fa-dribbble', 'fa-dropbox', 'fa-drupal', 'fa-facebook', 'fa-flickr', 'fa-foursquare', 'fa-get-pocket', 'fa-git', 'fa-github', 'fa-github-alt', 'fa-gittip', 'fa-google', 'fa-google-plus', 'fa-google-wallet', 'fa-gratipay', 'fa-hacker-news', 'fa-instagram', 'fa-ioxhost', 'fa-joomla', 'fa-jsfiddle', 'fa-lastfm', 'fa-leanpub', 'fa-linkedin', 'fa-meanpath', 'fa-medium', 'fa-odnoklassniki', 'fa-opencart', 'fa-pagelines', 'fa-paypal', 'fa-pied-piper-alt', 'fa-pinterest-p', 'fa-qq', 'fa-reddit', 'fa-renren', 'fa-sellsy', 'fa-share-alt', 'fa-shirtsinbulk', 'fa-simplybuilt', 'fa-skyatlas', 'fa-skype', 'fa-slack', 'fa-slideshare', 'fa-soundcloud', 'fa-spotify', 'fa-stack-exchange', 'fa-stack-overflow', 'fa-steam', 'fa-stumbleupon', 'fa-tencent-weibo', 'fa-trello', 'fa-tripadvisor', 'fa-tumblr', 'fa-twitch', 'fa-twitter', 'fa-viacoin', 'fa-vimeo', 'fa-vine', 'fa-vk', 'fa-wechat', 'fa-weibo', 'fa-weixin', 'fa-whatsapp', 'fa-wordpress', 'fa-xing', 'fa-y-combinator', 'fa-yelp', 'fa-youtube-play']
+ social: ['fa-globe', 'fa-amazon', 'fa-angellist', 'fa-apple', 'fa-behance', 'fa-bitbucket', 'fa-codepen', 'fa-connectdevelop', 'fa-dashcube', 'fa-delicious', 'fa-deviantart', 'fa-digg', 'fa-dribbble', 'fa-dropbox', 'fa-drupal', 'fa-facebook', 'fa-flickr', 'fa-foursquare', 'fa-get-pocket', 'fa-git', 'fa-github', 'fa-github-alt', 'fa-gittip', 'fa-google', 'fa-google-plus', 'fa-google-wallet', 'fa-gratipay', 'fa-hacker-news', 'fa-instagram', 'fa-ioxhost', 'fa-joomla', 'fa-jsfiddle', 'fa-lastfm', 'fa-leanpub', 'fa-linkedin', 'fa-meanpath', 'fa-medium', 'fa-odnoklassniki', 'fa-opencart', 'fa-pagelines', 'fa-paypal', 'fa-pied-piper-alt', 'fa-pinterest-p', 'fa-qq', 'fa-reddit', 'fa-renren', 'fa-sellsy', 'fa-share-alt', 'fa-shirtsinbulk', 'fa-simplybuilt', 'fa-skyatlas', 'fa-skype', 'fa-slack', 'fa-slideshare', 'fa-soundcloud', 'fa-spotify', 'fa-stack-exchange', 'fa-stack-overflow', 'fa-steam', 'fa-stumbleupon', 'fa-tencent-weibo', 'fa-trello', 'fa-tripadvisor', 'fa-tumblr', 'fa-twitch', 'fa-twitter', 'fa-viacoin', 'fa-vimeo', 'fa-vine', 'fa-vk', 'fa-wechat', 'fa-weibo', 'fa-weixin', 'fa-whatsapp', 'fa-wordpress', 'fa-xing', 'fa-y-combinator', 'fa-yelp', 'fa-youtube-play']
};
}
}, {
@@ -33,20 +156,20 @@ System.register('Davis/SocialProfile/components/IconSelectorComponent', ['flarum
value: function view() {
var _this2 = this;
- $(".iconpicker-image-" + this.props.index()).error(function () {
+ $('.iconpicker-image-' + this.props.index()).error(function () {
_this2.props.favicon('none');
- _this2.props.selection(_this2.icons['social'][0]);
+ _this2.props.selection(_this2.icons.social[0]);
m.redraw();
});
this.props.children = this.items().toArray();
- return babelHelpers.get(Object.getPrototypeOf(IconSelectorComponent.prototype), 'view', this).call(this);
+ return babelHelpers.get(IconSelectorComponent.prototype.__proto__ || Object.getPrototypeOf(IconSelectorComponent.prototype), 'view', this).call(this);
}
}, {
key: 'getButtonContent',
value: function getButtonContent() {
- return [/^favicon(-\w+)?$/.test(this.props.selection()) ? [m('img', { 'class': this.props.selection() == 'favicon-grey' ? 'social-greyscale-button' : 'social-button', style: 'width: 14px;height: 14px;', src: this.props.favicon() })] : icon(this.props.selection().replace('fa-', ''), {}), this.props.caretIcon ? icon(this.props.caretIcon, { className: 'Button-caret' }) : ''];
+ return [/^favicon(-\w+)?$/.test(this.props.selection()) ? [m('img', { className: this.props.selection() === 'favicon-grey' ? 'social-greyscale-button' : 'social-button', style: { width: '14px', height: '14px' }, alt: 'favicon', src: this.props.favicon() })] : icon(this.props.selection().replace('fa-', ''), {}), this.props.caretIcon ? icon(this.props.caretIcon, { className: 'Button-caret' }) : ''];
}
}, {
key: 'items',
@@ -55,37 +178,31 @@ System.register('Davis/SocialProfile/components/IconSelectorComponent', ['flarum
var items = new ItemList();
- if (this.props.favicon() != 'none') {
+ if (this.props.favicon() !== 'none') {
items.add('favicon', m('div', { onclick: function onclick() {
_this3.props.selection('favicon');m.redraw();
- }, role: "button", href: "#", class: "iconpicker-item " + (this.props.selection() == 'favicon' ? "iconpicker--highlighted" : ""), title: 'Favicon' }, [m('img', { 'class': "iconpicker-image-" + this.props.index(), style: 'width: 14px;height: 14px;margin: 0 2px 0 2px;', src: this.props.favicon() })]), 102);
+ }, role: 'button', href: '#', class: 'iconpicker-item ' + (this.props.selection() === 'favicon' ? 'iconpicker--highlighted' : ''), title: 'Favicon' }, [m('img', { className: 'iconpicker-image-' + this.props.index(), alt: 'favicon', style: { width: '14px', height: '14px', margin: '0 2px 0 2px' }, src: this.props.favicon() })]), 102);
items.add('favicon-grey', m('div', { onclick: function onclick() {
_this3.props.selection('favicon-grey');m.redraw();
- }, role: "button", href: "#", class: "iconpicker-item-invt " + (this.props.selection() == 'favicon-grey' ? "iconpicker--highlighted" : ""), title: 'Grey Favicon' }, [m('img', { 'class': "social-greyscale-button iconpicker-image-" + this.props.index(), style: 'width: 14px;height: 14px;margin: 0 2px 0 2px;', src: this.props.favicon() })]), 101);
+ }, role: 'button', href: '#', class: 'iconpicker-item-invt ' + (this.props.selection() === 'favicon-grey' ? 'iconpicker--highlighted' : ''), title: 'Grey Favicon' }, [m('img', { className: 'social-greyscale-button iconpicker-image-' + this.props.index(), alt: 'favicon', style: { width: '14px', height: '14px', margin: '0 2px 0 2px' }, src: this.props.favicon() })]), 101);
}
- var _loop = function _loop(k) {
- highlighted = m.prop();
-
- if (_this3.props.selection() == _this3.icons['social'][k]) {
+ this.icons.social.forEach(function (curIcon) {
+ var highlighted = m.prop();
+ if (_this3.props.selection() === curIcon) {
highlighted('iconpicker--highlighted');
}
- items.add(_this3.icons['social'][k], m('div', { onclick: function onclick() {
- _this3.props.selection(_this3.icons['social'][k]);m.redraw();
- }, role: "button", href: "#", class: "iconpicker-item " + highlighted(), title: '.' + _this3.icons['social'][k] }, [icon(_this3.icons['social'][k].replace('fa-', ''), { className: 'social-icon' })]), 100);
- };
-
- for (var k in this.icons['social']) {
- var highlighted;
+ items.add(curIcon, m('div', { onclick: function onclick() {
+ _this3.props.selection(curIcon);m.redraw();
+ }, role: 'button', href: '#', class: 'iconpicker-item ' + highlighted(), title: '.' + curIcon }, [icon(curIcon.replace('fa-', ''), { className: 'social-icon' })]), 100);
+ });
- _loop(k);
- }
return items;
}
}], [{
key: 'initProps',
value: function initProps(props) {
- babelHelpers.get(Object.getPrototypeOf(IconSelectorComponent), 'initProps', this).call(this, props);
+ babelHelpers.get(IconSelectorComponent.__proto__ || Object.getPrototypeOf(IconSelectorComponent), 'initProps', this).call(this, props);
props.className = 'icondropdown';
props.buttonClassName = 'Button Button--icon';
@@ -101,15 +218,15 @@ System.register('Davis/SocialProfile/components/IconSelectorComponent', ['flarum
});;
'use strict';
-System.register('Davis/SocialProfile/components/SocialButtonsModal', ['flarum/components/Modal', 'flarum/components/Button', 'flarum/utils/string', 'Davis/SocialProfile/components/WebsiteInputComponent'], function (_export, _context) {
- var Modal, Button, slug, WebsiteInputComponent, SocialButtonsModal;
+System.register('Davis/SocialProfile/components/SocialButtonsModal', ['flarum/components/Modal', 'flarum/components/Button', 'Davis/SocialProfile/components/WebsiteInputComponent'], function (_export, _context) {
+ "use strict";
+
+ var Modal, Button, WebsiteInputComponent, SocialButtonsModal;
return {
setters: [function (_flarumComponentsModal) {
Modal = _flarumComponentsModal.default;
}, function (_flarumComponentsButton) {
Button = _flarumComponentsButton.default;
- }, function (_flarumUtilsString) {
- slug = _flarumUtilsString.slug;
}, function (_DavisSocialProfileComponentsWebsiteInputComponent) {
WebsiteInputComponent = _DavisSocialProfileComponentsWebsiteInputComponent.default;
}],
@@ -119,25 +236,27 @@ System.register('Davis/SocialProfile/components/SocialButtonsModal', ['flarum/co
function SocialButtonsModal() {
babelHelpers.classCallCheck(this, SocialButtonsModal);
- return babelHelpers.possibleConstructorReturn(this, Object.getPrototypeOf(SocialButtonsModal).apply(this, arguments));
+ return babelHelpers.possibleConstructorReturn(this, (SocialButtonsModal.__proto__ || Object.getPrototypeOf(SocialButtonsModal)).apply(this, arguments));
}
babelHelpers.createClass(SocialButtonsModal, [{
key: 'init',
value: function init() {
+ var _this2 = this;
- babelHelpers.get(Object.getPrototypeOf(SocialButtonsModal.prototype), 'init', this).call(this);
+ babelHelpers.get(SocialButtonsModal.prototype.__proto__ || Object.getPrototypeOf(SocialButtonsModal.prototype), 'init', this).call(this);
this.buttons = [];
- if (this.props.data == true) {
- this.createButtonObject(0);
- } else {
- for (var k in this.props.data) {
- if (this.props.data[k]['title'] != "") {
- var button = this.props.data[k];
- this.createButtonObject(k, button);
+ var buttons = JSON.parse(this.props.user.data.attributes.socialButtons || '[]');
+
+ if (buttons.length) {
+ buttons.forEach(function (button, index) {
+ if (button.title !== '') {
+ _this2.createButtonObject(index, button);
}
- }
+ });
+ } else {
+ this.createButtonObject(0);
}
}
}, {
@@ -153,27 +272,33 @@ System.register('Davis/SocialProfile/components/SocialButtonsModal', ['flarum/co
}, {
key: 'content',
value: function content() {
- var _this2 = this;
+ var _this3 = this;
$('.Modal-content').css('overflow', 'visible');
return [m('div', { className: 'Modal-body' }, [m('div', { className: 'Form' }, [this.buttons.map(function (button) {
- return [WebsiteInputComponent.component({
- button: button
- })];
- }), m('div', { className: 'Form-group', id: 'submit-button-group' }, [m('div', { className: 'Button Button--primary EditSocialButtons-add', style: 'margin-left: 1%;',
+ return WebsiteInputComponent.component({ button: button });
+ }), m('div', { className: 'Form-group', id: 'submit-button-group' }, [m('div', {
+ className: 'Button Button--primary EditSocialButtons-add',
+ style: 'margin-left: 1%;',
onclick: function onclick() {
- _this2.createButtonObject(_this2.buttons.length);
+ _this3.createButtonObject(_this3.buttons.length);
m.redraw();
- $('#socialgroup' + (_this2.buttons.length - 1)).delay(150).slideDown();
- } }, [m('i', { className: 'fa fa-fw fa-plus' })]), m('div', { className: 'Button Button--primary EditSocialButtons-del', style: 'margin-left: 1%;',
+ $('document').ready(function () {
+ $('#socialgroup-' + (_this3.buttons.length - 1)).slideDown();
+ });
+ }
+ }, [m('i', { className: 'fa fa-fw fa-plus' })]), m('div', {
+ className: 'Button Button--primary EditSocialButtons-del',
+ style: 'margin-left: 1%;',
onclick: function onclick() {
- var curdel = _this2.buttons.length - 1;
- $('#socialgroup' + curdel).slideUp('normal', function () {
- _this2.buttons.splice(curdel, 1);
+ var curdel = _this3.buttons.length - 1;
+ $('#socialgroup-' + curdel).slideUp('normal', function () {
+ _this3.buttons.splice(curdel, 1);
m.redraw();
});
- } }, [m('i', { className: 'fa fa-fw fa-minus' })]), Button.component({
+ }
+ }, [m('i', { className: 'fa fa-fw fa-minus' })]), Button.component({
type: 'submit',
style: 'float: right;',
className: 'Button Button--primary EditSocialButtons-save',
@@ -181,61 +306,59 @@ System.register('Davis/SocialProfile/components/SocialButtonsModal', ['flarum/co
children: app.translator.trans('davis-socialprofile.forum.edit.submit')
})])])])];
}
+ }, {
+ key: 'data',
+ value: function data() {
+ var buttons = [];
+
+ this.buttons.forEach(function (button, index) {
+ if (button.title() !== '') {
+ buttons[index] = {};
+ buttons[index].title = button.title();
+ buttons[index].url = button.url();
+ buttons[index].icon = button.icon();
+ buttons[index].favicon = button.favicon();
+ }
+ });
+
+ return {
+ socialButtons: JSON.stringify(buttons)
+ };
+ }
}, {
key: 'onsubmit',
value: function onsubmit(e) {
- var _this3 = this;
+ var _this4 = this;
e.preventDefault();
this.loading = true;
- this.finbuttons = [];
- for (var k in this.buttons) {
- if (this.buttons[k].title() != "") {
- var number = this.finbuttons.length;
- this.finbuttons[number] = {};
- this.finbuttons[number].title = m.prop(this.buttons[k].title());
- this.finbuttons[number].url = m.prop(this.buttons[k].url());
- this.finbuttons[number].icon = m.prop(this.buttons[k].icon());
- this.finbuttons[number].favicon = m.prop(this.buttons[k].favicon());
- }
- }
- this.finbuttons = JSON.stringify(this.finbuttons);
- var data = new FormData();
- data.append('buttons', this.finbuttons);
- app.request({
- method: 'POST',
- url: app.forum.attribute('apiUrl') + '/profile/socialbuttons',
- serialize: function serialize(raw) {
- return raw;
- },
- data: data
- }).then(function () {
- $('#app').trigger("refreshSocialButtons", [_this3.finbuttons]);
- _this3.hide();
- }, function (response) {
- _this3.loading = false;
- _this3.handleErrors(response);
+
+ this.props.user.save(this.data(), { errorHandler: this.onerror.bind(this) }).then(this.hide.bind(this)).then($('#app').trigger('refreshSocialButtons', [this.data().socialButtons])).catch(function () {
+ _this4.loading = false;
+ m.redraw();
});
}
}, {
key: 'createButtonObject',
value: function createButtonObject(key) {
- var button = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
+ var button = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if (button == null) {
- button = {};
- button['favicon'] = 'none';
- button['title'] = '';
- button['url'] = '';
- button['icon'] = 'globe';
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop('none');
+ this.buttons[key].title = m.prop('');
+ this.buttons[key].url = m.prop('');
+ this.buttons[key].icon = m.prop('globe');
+ } else {
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop(button.favicon);
+ this.buttons[key].title = m.prop(button.title);
+ this.buttons[key].url = m.prop(button.url);
+ this.buttons[key].icon = m.prop(button.icon);
}
- this.buttons[key] = {};
- this.buttons[key].index = m.prop(key);
- this.buttons[key].favicon = m.prop(button["favicon"]);
- this.buttons[key].title = m.prop(button["title"]);
- this.buttons[key].url = m.prop(button["url"]);
- this.buttons[key].icon = m.prop(button["icon"]);
}
}]);
return SocialButtonsModal;
@@ -247,13 +370,13 @@ System.register('Davis/SocialProfile/components/SocialButtonsModal', ['flarum/co
});;
'use strict';
-System.register('Davis/SocialProfile/components/WebsiteInputComponent', ['flarum/Component', 'flarum/utils/extract', 'Davis/SocialProfile/components/IconSelectorComponent'], function (_export, _context) {
- var Component, extract, IconSelectorComponent, WebsiteInputComponent;
+System.register('Davis/SocialProfile/components/WebsiteInputComponent', ['flarum/Component', 'Davis/SocialProfile/components/IconSelectorComponent'], function (_export, _context) {
+ "use strict";
+
+ var Component, IconSelectorComponent, WebsiteInputComponent;
return {
setters: [function (_flarumComponent) {
Component = _flarumComponent.default;
- }, function (_flarumUtilsExtract) {
- extract = _flarumUtilsExtract.default;
}, function (_DavisSocialProfileComponentsIconSelectorComponent) {
IconSelectorComponent = _DavisSocialProfileComponentsIconSelectorComponent.default;
}],
@@ -263,13 +386,13 @@ System.register('Davis/SocialProfile/components/WebsiteInputComponent', ['flarum
function WebsiteInputComponent() {
babelHelpers.classCallCheck(this, WebsiteInputComponent);
- return babelHelpers.possibleConstructorReturn(this, Object.getPrototypeOf(WebsiteInputComponent).apply(this, arguments));
+ return babelHelpers.possibleConstructorReturn(this, (WebsiteInputComponent.__proto__ || Object.getPrototypeOf(WebsiteInputComponent)).apply(this, arguments));
}
babelHelpers.createClass(WebsiteInputComponent, [{
key: 'init',
value: function init() {
- babelHelpers.get(Object.getPrototypeOf(WebsiteInputComponent.prototype), 'init', this).call(this);
+ babelHelpers.get(WebsiteInputComponent.prototype.__proto__ || Object.getPrototypeOf(WebsiteInputComponent.prototype), 'init', this).call(this);
this.button = this.props.button;
}
@@ -278,63 +401,59 @@ System.register('Davis/SocialProfile/components/WebsiteInputComponent', ['flarum
value: function view() {
var _this2 = this;
- return m(
- 'div',
- {
- className: 'Form-group form-group-social',
- id: 'socialgroup' + this.button.index()
- },
- m('input', {
- className: 'SocialFormControl SocialTitle',
- placeholder: app.translator.trans('davis-socialprofile.forum.edit.title'),
- value: this.button.title(),
- oninput: m.withAttr('value', this.button.title) }),
- IconSelectorComponent.component({
- selection: this.button.icon,
- favicon: this.button.favicon,
- index: this.button.index
- }),
- m('input', {
- className: 'SocialFormControl Socialurl',
- placeholder: app.translator.trans('davis-socialprofile.forum.edit.url'),
- value: this.button.url(),
- oninput: m.withAttr('value', function (value) {
- _this2.button.url(value);
- clearTimeout(_this2.waittilfinsihed);
- if (_this2.button.icon() !== 'fa-circle-o-notch fa-spin') {
- _this2.button.icon('fa-circle-o-notch fa-spin');
+ return m('div', {
+ className: 'Form-group form-group-social',
+ id: 'socialgroup-' + this.button.index()
+ }, [m('input', {
+ className: 'SocialFormControl SocialTitle',
+ placeholder: app.translator.trans('davis-socialprofile.forum.edit.title'),
+ tabIndex: (this.button.index() + 1) * 2 - 1,
+ value: this.button.title(),
+ onchange: m.withAttr('value', this.button.title)
+ }), IconSelectorComponent.component({
+ selection: this.button.icon,
+ favicon: this.button.favicon,
+ index: this.button.index
+ }), m('input', {
+ className: 'SocialFormControl Socialurl',
+ placeholder: app.translator.trans('davis-socialprofile.forum.edit.url'),
+ tabIndex: (this.button.index() + 1) * 2,
+ value: this.button.url(),
+ onchange: m.withAttr('value', function (value) {
+ _this2.button.url(value);
+ clearTimeout(_this2.waittilfinsihed);
+ if (_this2.button.icon() !== 'fa-circle-o-notch fa-spin') {
+ _this2.button.icon('fa-circle-o-notch fa-spin');
+ _this2.button.favicon('none');
+ }
+ _this2.waittilfinsihed = setTimeout(function () {
+ var urlpattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/;
+
+ if (urlpattern.test(_this2.button.url().toLowerCase())) {
+ var iconurl = _this2.button.url().replace(/(:\/\/[^\/]+).*$/, '$1') + '\n /favicon.ico';
+ _this2.button.favicon(iconurl);
+ _this2.button.icon('favicon');
+ m.redraw();
+ } else {
+ _this2.button.icon('fa-globe');
_this2.button.favicon('none');
+ m.redraw();
}
- _this2.waittilfinsihed = setTimeout(function () {
- var urlpattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/;
- if (urlpattern.test(_this2.button.url().toLowerCase())) {
- var iconurl = _this2.button.url().replace(/(:\/\/[^\/]+).*$/, '$1') + '/favicon.ico';
- _this2.button.favicon(iconurl);
- _this2.button.icon('favicon');
- m.redraw();
- } else {
- _this2.button.icon('fa-globe');
- _this2.button.favicon('none');
- m.redraw();
- }
- }, 1000);
- })
- }),
- m('input', {
- className: 'SocialFormControl SocialIcon',
- id: 'icon' + this.button.index(),
- style: 'display: none',
- value: this.button.icon(),
- onchange: m.withAttr('value', this.button.icon)
- }),
- m('input', {
- className: 'SocialFormControl Socialfavicon',
- id: 'favicon' + this.button.index(),
- style: 'display: none',
- value: this.button.favicon(),
- onchange: m.withAttr('value', this.button.favicon)
+ }, 1000);
})
- );
+ }), m('input', {
+ className: 'SocialFormControl SocialIcon',
+ id: 'icon' + this.button.index(),
+ style: { display: 'none' },
+ value: this.button.icon(),
+ onchange: m.withAttr('value', this.button.icon)
+ }), m('input', {
+ className: 'SocialFormControl Socialfavicon',
+ id: 'favicon' + this.button.index(),
+ style: { display: 'none' },
+ value: this.button.favicon(),
+ onchange: m.withAttr('value', this.button.favicon)
+ })]);
}
}]);
return WebsiteInputComponent;
@@ -346,136 +465,114 @@ System.register('Davis/SocialProfile/components/WebsiteInputComponent', ['flarum
});;
'use strict';
-System.register('Davis/SocialProfile/main', ['flarum/app', 'flarum/extend', 'flarum/components/UserCard', 'flarum/components/Badge', 'Davis/SocialProfile/components/SocialButtonsModal'], function (_export, _context) {
- var app, extend, UserCard, Badge, SocialButtonsModal;
- return {
- setters: [function (_flarumApp) {
- app = _flarumApp.default;
- }, function (_flarumExtend) {
- extend = _flarumExtend.extend;
- }, function (_flarumComponentsUserCard) {
- UserCard = _flarumComponentsUserCard.default;
- }, function (_flarumComponentsBadge) {
- Badge = _flarumComponentsBadge.default;
- }, function (_DavisSocialProfileComponentsSocialButtonsModal) {
- SocialButtonsModal = _DavisSocialProfileComponentsSocialButtonsModal.default;
- }],
- execute: function () {
-
- app.initializers.add('davis-socialprofile-forum', function () {
-
- extend(UserCard.prototype, 'init', function () {
- var _this = this;
-
- var user = this.props.user;
- var apiUrl = app.forum.attribute('apiUrl') + '/profile/socialbutton/' + user.data.id;
- this.buttonsArray = null; //Indicate we haven't retrieved the user's buttons
- //Get buttons from database
- app.request({ method: "GET", url: apiUrl }).then(function (result) {
- //Test if user has set their buttons up already
- if (result.data.attributes.hasOwnProperty("buttons")) {
- //Test if buttons have been set up, but the array is empty
- if (result.data.attributes.buttons == "[]") {
- //Since there are no buttons set, we have a blank slate
- _this.buttonsArray = true; //Indicate we have retrieved the user's buttons
- _this.isBlankSlate = true; //Indicate we don't have any buttons
- } else {
- //The buttons array must not be empty, so lets set it
- _this.buttonsArray = JSON.parse(result.data.attributes.buttons);
- _this.isBlankSlate = false; //Indicate we do have buttons
- }
- } else {
- //This user has never set their buttons
- _this.buttonsArray = true; //Indicate we have retrieved the user's buttons
- _this.isBlankSlate = true; //Indicate we don't have any buttons
- }
- user.freshness = new Date(); //Tell Mithril we have new data
- m.redraw(); //Refresh the DOM
- });
-
- //If the buttons have been edited, we need to refresh them
- $('#app').on('refreshSocialButtons', function (e, buttons) {
- var user = _this.props.user; //Then is our user
- _this.buttonsArray = JSON.parse(buttons); //Parse the saved array from editing
- _this.isBlankSlate = false; //Indicate we do really have buttons
- user.freshness = new Date(); //Tell Mithril we have new data
- m.redraw(); //Refresh DOM
- });
- });
+System.register('Davis/SocialProfile/main', ['flarum/app', 'flarum/Model', 'flarum/models/User', 'flarum/extend', 'flarum/components/UserCard', 'flarum/components/Badge', 'Davis/SocialProfile/components/SocialButtonsModal', 'Davis/SocialProfile/components/DeleteButtonModal'], function (_export, _context) {
+ "use strict";
+
+ var app, Model, User, extend, UserCard, Badge, SocialButtonsModal, DeleteButtonModal;
+ return {
+ setters: [function (_flarumApp) {
+ app = _flarumApp.default;
+ }, function (_flarumModel) {
+ Model = _flarumModel.default;
+ }, function (_flarumModelsUser) {
+ User = _flarumModelsUser.default;
+ }, function (_flarumExtend) {
+ extend = _flarumExtend.extend;
+ }, function (_flarumComponentsUserCard) {
+ UserCard = _flarumComponentsUserCard.default;
+ }, function (_flarumComponentsBadge) {
+ Badge = _flarumComponentsBadge.default;
+ }, function (_DavisSocialProfileComponentsSocialButtonsModal) {
+ SocialButtonsModal = _DavisSocialProfileComponentsSocialButtonsModal.default;
+ }, function (_DavisSocialProfileComponentsDeleteButtonModal) {
+ DeleteButtonModal = _DavisSocialProfileComponentsDeleteButtonModal.default;
+ }],
+ execute: function () {
- extend(UserCard.prototype, 'infoItems', function (items) {
- var _this2 = this;
-
- // If request hasn't loaded yet, don't add any items.
- if (!this.buttonsArray) return;
-
- //If there are buttons, add them
- if (!this.isBlankSlate) {
- var _loop = function _loop(k) {
- var selectedButton = _this2.buttonsArray[k]; //Set constant for easier selection
- //Ensure the button has a title, icon, and url
- if (selectedButton["title"] !== "" && selectedButton["icon"] !== "" && selectedButton["url"] !== "") {
- //If the button is using a favicon, make sure it is displayed
- if (selectedButton['icon'] == 'favicon' || selectedButton['icon'] == 'favicon-grey') {
- buttonStyle = 'background-image: url("' + selectedButton['favicon'] + '");background-size: 60%;background-position: 50% 50%;background-repeat: no-repeat;';
- //If the favicon is set to greyscale, make sure it is displayed
- if (selectedButton['icon'] == 'favicon-grey') {
- buttonClass = selectedButton["icon"] + '-' + k + ' social-button social-greyscale-button';
- } else {
- buttonClass = selectedButton["icon"] + '-' + k + ' social-button';
- }
- } else {
- buttonStyle = '';
- buttonClass = selectedButton["icon"] + '-' + k + ' social-button';
- }
- //Acctually add the button
- items.add(buttonClass, Badge.component({
- type: "social social-icon-" + k,
- icon: selectedButton["icon"].replace('fa-', ''),
- label: selectedButton["title"],
- style: buttonStyle,
- onclick: function onclick() {
- window.open(selectedButton["url"], '_blank');
- }
- }));
- }
- };
-
- //Loop through the buttonsArray
- for (var k in this.buttonsArray) {
- var buttonStyle, buttonClass;
-
- _loop(k);
- }
- //Add the edit buttons at the end, as long as it's their own profile
- if (app.session.user === app.current.user && app.session.user !== undefined && app.current.user !== undefined) {
- //Add the settings button
- items.add('settings social-button', Badge.component({
- type: "social social-settings",
- icon: 'cog',
- label: app.translator.trans('davis-socialprofile.forum.edit.edit'),
- onclick: function onclick() {
- app.modal.show(new SocialButtonsModal({ data: _this2.buttonsArray })); //Show the edit modal
- }
- }), -1);
- }
- //It turns out they don't have any buttons
+ app.initializers.add('davis-socialprofile-forum', function () {
+ User.prototype.socialButtons = Model.attribute('socialButtons');
+
+ extend(UserCard.prototype, 'init', function () {
+ var _this = this;
+
+ $('#app').on('refreshSocialButtons', function (e, buttons) {
+ _this.buttons = JSON.parse(buttons || '[]');
+ _this.props.user.data.attributes.socialButtons = JSON.parse(buttons || '[]');
+ _this.props.user.freshness = new Date();
+ m.redraw();
+ });
+ });
+
+ extend(UserCard.prototype, 'infoItems', function (items) {
+ var _this2 = this;
+
+ this.isSelf = app.session.user === this.props.user;
+ this.canEdit = app.session.user ? app.session.user.data.attributes.canEdit : false;
+ this.buttons = JSON.parse(this.props.user.data.attributes.socialButtons || '[]');
+
+ if (this.buttons.length) {
+ this.buttons.forEach(function (button, index) {
+ if (button.title !== '' && button.icon !== '' && button.url !== '') {
+ var buttonStyle = '';
+ var buttonClassName = '';
+
+ if (button.icon === 'favicon' || button.icon === 'favicon-grey') {
+ buttonStyle = 'background-image: url("' + button.favicon + '");background-size: 60%;background-position: 50% 50%;background-repeat: no-repeat;';
+ if (button.icon === 'favicon-grey') {
+ buttonClassName = button.icon + '-' + index + ' social-button social-greyscale-button';
+ } else {
+ buttonClassName = button.icon + '-' + index + ' social-button';
+ }
+ } else {
+ buttonStyle = '';
+ buttonClassName = button.icon + '-' + index + ' social-button';
+ }
+ items.add('' + buttonClassName + (_this2.deleting ? ' social-button--highlightable' : ''), Badge.component({
+ type: 'social social-icon-' + index,
+ icon: button.icon.replace('fa-', ''),
+ label: button.title,
+ style: buttonStyle,
+ onclick: function onclick() {
+ if (_this2.deleting) {
+ app.modal.show(new DeleteButtonModal({ user: _this2.props.user, index: index }));
} else {
- //Add an add button only if its their own profile
- if (app.session.user === app.current.user && app.session.user !== undefined && app.current.user !== undefined) {
- //Add the add button
- items.add('settings social-button', Badge.component({
- type: "social null-social-settings",
- icon: "plus",
- label: app.translator.trans('davis-socialprofile.forum.edit.add'),
- onclick: function onclick() {
- app.modal.show(new SocialButtonsModal({ data: _this2.buttonsArray }));
- }
- }), -1);
- }
- }
- });
+ window.open(button.url, '_blank');
+ }
+ }
+ }));
+ }
});
- }
- };
+ if (this.isSelf) {
+ items.add('settings social-button', Badge.component({
+ type: 'social social-settings',
+ icon: 'cog',
+ label: app.translator.trans('davis-socialprofile.forum.edit.edit'),
+ onclick: function onclick() {
+ app.modal.show(new SocialButtonsModal({ user: _this2.props.user }));
+ }
+ }), -1);
+ } else if (this.canEdit) {
+ items.add('settings social-button', Badge.component({
+ type: 'social social-moderate ' + (this.deleting ? 'social-moderate--highlighted' : ''),
+ icon: 'exclamation-triangle',
+ label: app.translator.trans('davis-socialprofile.forum.edit.delete'),
+ onclick: function onclick() {
+ _this2.deleting = !_this2.deleting;
+ }
+ }), -1);
+ }
+ } else if (this.isSelf) {
+ items.add('settings social-button', Badge.component({
+ type: 'social null-social-settings',
+ icon: 'plus',
+ label: app.translator.trans('davis-socialprofile.forum.edit.add'),
+ onclick: function onclick() {
+ app.modal.show(new SocialButtonsModal({ user: _this2.props.user }));
+ }
+ }), -1);
+ }
+ });
+ });
+ }
+ };
});
\ No newline at end of file
diff --git a/js/forum/package.json b/js/forum/package.json
index 34e1b71..2bdaf6a 100644
--- a/js/forum/package.json
+++ b/js/forum/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"devDependencies": {
- "gulp": "^3.8.11",
- "flarum-gulp": "^0.2.0"
+ "gulp": "^3.9.1",
+ "flarum-gulp": "dav-is/flarum-gulp#patch-1"
}
}
\ No newline at end of file
diff --git a/js/forum/src/components/DeleteButtonModal.js b/js/forum/src/components/DeleteButtonModal.js
new file mode 100644
index 0000000..8d1051e
--- /dev/null
+++ b/js/forum/src/components/DeleteButtonModal.js
@@ -0,0 +1,96 @@
+import Modal from 'flarum/components/Modal';
+import Button from 'flarum/components/Button';
+
+export default class DeleteButtonModal extends Modal {
+ init() {
+ super.init();
+
+ this.buttons = [];
+ this.index = this.props.index;
+ const buttons = JSON.parse(this.props.user.data.attributes.socialButtons || '[]');
+ this.button = buttons[this.index];
+
+ buttons.forEach((button, index) => {
+ this.createButtonObject(index, button);
+ });
+ }
+
+ className() {
+ return 'SocialButtonsModal Modal--small';
+ }
+
+ title() {
+ return app.translator.trans('davis-socialprofile.forum.edit.deletetitle');
+ }
+
+ content() {
+ $('.Modal-content').css('overflow', 'visible');
+ return [
+ m('div', { className: 'Modal-body' }, [
+ m('div', { className: 'Form' }, [
+ m('h3', { className: 'SocialProfile-title' }, this.button.title),
+ m('p', { className: 'SocialProfile-url' }, this.button.url),
+ m('div', { className: 'Form-group', id: 'submit-button-group' }, [
+ Button.component({
+ type: 'submit',
+ className: 'Button Button--primary EditSocialButtons-delete',
+ loading: this.loading,
+ children: app.translator.trans('davis-socialprofile.forum.edit.delete'),
+ }),
+ ]),
+ ]),
+ ]),
+ ];
+ }
+
+ data() {
+ const buttons = [];
+
+ this.buttons.forEach((button, index) => {
+ if (button.title() !== '') {
+ buttons[index] = {};
+ buttons[index].title = button.title();
+ buttons[index].url = button.url();
+ buttons[index].icon = button.icon();
+ buttons[index].favicon = button.favicon();
+ }
+ });
+
+ return {
+ socialButtons: JSON.stringify(buttons),
+ };
+ }
+
+ onsubmit(e) {
+ e.preventDefault();
+
+ this.loading = true;
+ this.buttons.splice(this.index, 1);
+
+ this.props.user.save(this.data(), { errorHandler: this.onerror.bind(this) })
+ .then(this.hide.bind(this))
+ .then($('#app').trigger('refreshSocialButtons', [this.data().socialButtons]))
+ .catch(() => {
+ this.loading = false;
+ m.redraw();
+ });
+ }
+
+ createButtonObject(key, button = null) {
+ if (button == null) {
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop('none');
+ this.buttons[key].title = m.prop('');
+ this.buttons[key].url = m.prop('');
+ this.buttons[key].icon = m.prop('globe');
+ } else {
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop(button.favicon);
+ this.buttons[key].title = m.prop(button.title);
+ this.buttons[key].url = m.prop(button.url);
+ this.buttons[key].icon = m.prop(button.icon);
+ }
+ }
+}
diff --git a/js/forum/src/components/IconSelectorComponent.js b/js/forum/src/components/IconSelectorComponent.js
index 3bc46b2..cac4d9f 100644
--- a/js/forum/src/components/IconSelectorComponent.js
+++ b/js/forum/src/components/IconSelectorComponent.js
@@ -10,24 +10,23 @@ export default class IconSelectorComponent extends Dropdown {
props.buttonClassName = 'Button Button--icon';
props.menuClassName = 'social-dropdown-menu';
}
-
+
init() {
super.init();
-
+
this.icons = {
- 'social':
- ["fa-globe", 'fa-amazon', 'fa-angellist', 'fa-apple', 'fa-behance', 'fa-bitbucket', 'fa-codepen', 'fa-connectdevelop', 'fa-dashcube', 'fa-delicious', 'fa-deviantart', 'fa-digg', 'fa-dribbble', 'fa-dropbox', 'fa-drupal', 'fa-facebook', 'fa-flickr', 'fa-foursquare', 'fa-get-pocket', 'fa-git', 'fa-github', 'fa-github-alt', 'fa-gittip', 'fa-google', 'fa-google-plus', 'fa-google-wallet', 'fa-gratipay', 'fa-hacker-news', 'fa-instagram', 'fa-ioxhost', 'fa-joomla', 'fa-jsfiddle', 'fa-lastfm', 'fa-leanpub', 'fa-linkedin', 'fa-meanpath', 'fa-medium', 'fa-odnoklassniki', 'fa-opencart', 'fa-pagelines', 'fa-paypal', 'fa-pied-piper-alt', 'fa-pinterest-p', 'fa-qq', 'fa-reddit', 'fa-renren', 'fa-sellsy', 'fa-share-alt', 'fa-shirtsinbulk', 'fa-simplybuilt', 'fa-skyatlas', 'fa-skype', 'fa-slack', 'fa-slideshare', 'fa-soundcloud', 'fa-spotify', 'fa-stack-exchange', 'fa-stack-overflow', 'fa-steam', 'fa-stumbleupon', 'fa-tencent-weibo', 'fa-trello', 'fa-tripadvisor', 'fa-tumblr', 'fa-twitch', 'fa-twitter', 'fa-viacoin', 'fa-vimeo', 'fa-vine', 'fa-vk', 'fa-wechat', 'fa-weibo', 'fa-weixin', 'fa-whatsapp', 'fa-wordpress', 'fa-xing', 'fa-y-combinator', 'fa-yelp', 'fa-youtube-play' ],
+ social:
+ ['fa-globe', 'fa-amazon', 'fa-angellist', 'fa-apple', 'fa-behance', 'fa-bitbucket', 'fa-codepen', 'fa-connectdevelop', 'fa-dashcube', 'fa-delicious', 'fa-deviantart', 'fa-digg', 'fa-dribbble', 'fa-dropbox', 'fa-drupal', 'fa-facebook', 'fa-flickr', 'fa-foursquare', 'fa-get-pocket', 'fa-git', 'fa-github', 'fa-github-alt', 'fa-gittip', 'fa-google', 'fa-google-plus', 'fa-google-wallet', 'fa-gratipay', 'fa-hacker-news', 'fa-instagram', 'fa-ioxhost', 'fa-joomla', 'fa-jsfiddle', 'fa-lastfm', 'fa-leanpub', 'fa-linkedin', 'fa-meanpath', 'fa-medium', 'fa-odnoklassniki', 'fa-opencart', 'fa-pagelines', 'fa-paypal', 'fa-pied-piper-alt', 'fa-pinterest-p', 'fa-qq', 'fa-reddit', 'fa-renren', 'fa-sellsy', 'fa-share-alt', 'fa-shirtsinbulk', 'fa-simplybuilt', 'fa-skyatlas', 'fa-skype', 'fa-slack', 'fa-slideshare', 'fa-soundcloud', 'fa-spotify', 'fa-stack-exchange', 'fa-stack-overflow', 'fa-steam', 'fa-stumbleupon', 'fa-tencent-weibo', 'fa-trello', 'fa-tripadvisor', 'fa-tumblr', 'fa-twitch', 'fa-twitter', 'fa-viacoin', 'fa-vimeo', 'fa-vine', 'fa-vk', 'fa-wechat', 'fa-weibo', 'fa-weixin', 'fa-whatsapp', 'fa-wordpress', 'fa-xing', 'fa-y-combinator', 'fa-yelp', 'fa-youtube-play'],
};
}
view() {
-
- $(".iconpicker-image-"+this.props.index()).error(() => {
+ $(`.iconpicker-image-${this.props.index()}`).error(() => {
this.props.favicon('none');
- this.props.selection(this.icons['social'][0]);
+ this.props.selection(this.icons.social[0]);
m.redraw();
});
-
+
this.props.children = this.items().toArray();
return super.view();
@@ -35,33 +34,34 @@ export default class IconSelectorComponent extends Dropdown {
getButtonContent() {
return [
- (/^favicon(-\w+)?$/.test(this.props.selection())) ? [
] : icon(this.props.selection().replace('fa-', ''), {}),
- this.props.caretIcon ? icon(this.props.caretIcon, {className: 'Button-caret'}) : ''
+ (/^favicon(-\w+)?$/.test(this.props.selection())) ? [
] : icon(this.props.selection().replace('fa-', ''), {}),
+ this.props.caretIcon ? icon(this.props.caretIcon, { className: 'Button-caret' }) : '',
];
}
-
+
items() {
const items = new ItemList();
-
- if(this.props.favicon() != 'none') {
- items.add('favicon',(
- m('div', {onclick: () => {this.props.selection('favicon'); m.redraw();}, role: "button", href: "#", class: "iconpicker-item "+(this.props.selection() == 'favicon' ? "iconpicker--highlighted" : ""), title: 'Favicon'}, [
])),
+
+ if (this.props.favicon() !== 'none') {
+ items.add('favicon', (
+ m('div', { onclick: () => { this.props.selection('favicon'); m.redraw(); }, role: 'button', href: '#', class: `iconpicker-item ${this.props.selection() === 'favicon' ? 'iconpicker--highlighted' : ''}`, title: 'Favicon' }, [
])),
102
);
- items.add('favicon-grey',(
- m('div', {onclick: () => {this.props.selection('favicon-grey'); m.redraw();}, role: "button", href: "#", class: "iconpicker-item-invt "+(this.props.selection() == 'favicon-grey' ? "iconpicker--highlighted" : ""), title: 'Grey Favicon'}, [
])),
+ items.add('favicon-grey', (
+ m('div', { onclick: () => { this.props.selection('favicon-grey'); m.redraw(); }, role: 'button', href: '#', class: `iconpicker-item-invt ${this.props.selection() === 'favicon-grey' ? 'iconpicker--highlighted' : ''}`, title: 'Grey Favicon' }, [
])),
101
);
}
-
- for(const k in this.icons['social']) {
- var highlighted = m.prop();
- if (this.props.selection() == this.icons['social'][k]) { highlighted('iconpicker--highlighted'); }
- items.add(this.icons['social'][k],(
- m('div', {onclick: () => {this.props.selection(this.icons['social'][k]); m.redraw();}, role: "button", href: "#", class: "iconpicker-item " + highlighted(), title: '.'+this.icons['social'][k]}, [icon(this.icons['social'][k].replace('fa-', ''), {className: 'social-icon'})])),
+
+ this.icons.social.forEach((curIcon) => {
+ const highlighted = m.prop();
+ if (this.props.selection() === curIcon) { highlighted('iconpicker--highlighted'); }
+ items.add(curIcon, (
+ m('div', { onclick: () => { this.props.selection(curIcon); m.redraw(); }, role: 'button', href: '#', class: `iconpicker-item ${highlighted()}`, title: `.${curIcon}` }, [icon(curIcon.replace('fa-', ''), { className: 'social-icon' })])),
100
);
- }
+ });
+
return items;
}
-}
\ No newline at end of file
+}
diff --git a/js/forum/src/components/SocialButtonsModal.js b/js/forum/src/components/SocialButtonsModal.js
index 85078f4..af63da5 100644
--- a/js/forum/src/components/SocialButtonsModal.js
+++ b/js/forum/src/components/SocialButtonsModal.js
@@ -1,23 +1,22 @@
import Modal from 'flarum/components/Modal';
import Button from 'flarum/components/Button';
-import { slug } from 'flarum/utils/string';
import WebsiteInputComponent from 'Davis/SocialProfile/components/WebsiteInputComponent';
export default class SocialButtonsModal extends Modal {
init() {
-
super.init();
this.buttons = [];
- if (this.props.data == true) {
- this.createButtonObject(0);
- } else {
- for(var k in this.props.data) {
- if(this.props.data[k]['title'] != "") {
- const button = this.props.data[k];
- this.createButtonObject(k, button);
+ const buttons = JSON.parse(this.props.user.data.attributes.socialButtons || '[]');
+
+ if (buttons.length) {
+ buttons.forEach((button, index) => {
+ if (button.title !== '') {
+ this.createButtonObject(index, button);
}
- }
+ });
+ } else {
+ this.createButtonObject(0);
}
}
@@ -31,99 +30,96 @@ export default class SocialButtonsModal extends Modal {
content() {
$('.Modal-content').css('overflow', 'visible');
- return [
- m('div', {className: 'Modal-body'}, [
- m('div', {className: 'Form'}, [
- this.buttons.map((button) => {
- return [
- WebsiteInputComponent.component({
- button: button,
- }),
- ];
- }),
- m('div', {className: 'Form-group', id: 'submit-button-group'}, [
- m('div', {className: 'Button Button--primary EditSocialButtons-add', style: 'margin-left: 1%;',
- onclick: () => {
- this.createButtonObject(this.buttons.length);
-
- m.redraw();
- $('#socialgroup'+(this.buttons.length - 1)).delay(150).slideDown();
- }}, [
- m('i', {className: 'fa fa-fw fa-plus'})
- ]),
- m('div', {className: 'Button Button--primary EditSocialButtons-del', style: 'margin-left: 1%;',
- onclick: () => {
- var curdel = (this.buttons.length - 1);
- $('#socialgroup'+curdel).slideUp('normal', () => {
- this.buttons.splice(curdel, 1);
- m.redraw();
- });
- }}, [
- m('i', {className: 'fa fa-fw fa-minus'})
- ]),
- Button.component({
- type: 'submit',
- style: 'float: right;',
- className: 'Button Button--primary EditSocialButtons-save',
- loading: this.loading,
- children: app.translator.trans('davis-socialprofile.forum.edit.submit')
- }),
- ]),
- ]),
- ]),
- ];
+ return [
+ m('div', { className: 'Modal-body' }, [
+ m('div', { className: 'Form' }, [
+ this.buttons.map(button => WebsiteInputComponent.component({ button })),
+ m('div', { className: 'Form-group', id: 'submit-button-group' }, [
+ m('div', {
+ className: 'Button Button--primary EditSocialButtons-add',
+ style: 'margin-left: 1%;',
+ onclick: () => {
+ this.createButtonObject(this.buttons.length);
+
+ m.redraw();
+ $('document').ready(() => { $(`#socialgroup-${this.buttons.length - 1}`).slideDown(); });
+ },
+ }, [
+ m('i', { className: 'fa fa-fw fa-plus' }),
+ ]),
+ m('div', {
+ className: 'Button Button--primary EditSocialButtons-del',
+ style: 'margin-left: 1%;',
+ onclick: () => {
+ const curdel = (this.buttons.length - 1);
+ $(`#socialgroup-${curdel}`).slideUp('normal', () => {
+ this.buttons.splice(curdel, 1);
+ m.redraw();
+ });
+ },
+ }, [
+ m('i', { className: 'fa fa-fw fa-minus' }),
+ ]),
+ Button.component({
+ type: 'submit',
+ style: 'float: right;',
+ className: 'Button Button--primary EditSocialButtons-save',
+ loading: this.loading,
+ children: app.translator.trans('davis-socialprofile.forum.edit.submit'),
+ }),
+ ]),
+ ]),
+ ]),
+ ];
}
- onsubmit(e) {
-
- e.preventDefault();
-
- this.loading = true;
- this.finbuttons = [];
- for(var k in this.buttons) {
- if (this.buttons[k].title() != "") {
- var number = this.finbuttons.length
- this.finbuttons[number] = {};
- this.finbuttons[number].title = m.prop(this.buttons[k].title());
- this.finbuttons[number].url = m.prop(this.buttons[k].url());
- this.finbuttons[number].icon = m.prop(this.buttons[k].icon());
- this.finbuttons[number].favicon = m.prop(this.buttons[k].favicon());
- }
+ data() {
+ const buttons = [];
+
+ this.buttons.forEach((button, index) => {
+ if (button.title() !== '') {
+ buttons[index] = {};
+ buttons[index].title = button.title();
+ buttons[index].url = button.url();
+ buttons[index].icon = button.icon();
+ buttons[index].favicon = button.favicon();
}
- this.finbuttons = JSON.stringify(this.finbuttons);
- const data = new FormData();
- data.append('buttons', this.finbuttons);
- app.request({
- method: 'POST',
- url: app.forum.attribute('apiUrl') + '/profile/socialbuttons',
- serialize: raw => raw,
- data
- }).then(
- () => {
- $('#app').trigger("refreshSocialButtons", [this.finbuttons]);
- this.hide();
- },
- response => {
- this.loading = false;
- this.handleErrors(response);
- }
- );
+ });
+ return {
+ socialButtons: JSON.stringify(buttons),
+ };
}
-
+
+ onsubmit(e) {
+ e.preventDefault();
+
+ this.loading = true;
+
+ this.props.user.save(this.data(), { errorHandler: this.onerror.bind(this) })
+ .then(this.hide.bind(this))
+ .then($('#app').trigger('refreshSocialButtons', [this.data().socialButtons]))
+ .catch(() => {
+ this.loading = false;
+ m.redraw();
+ });
+ }
+
createButtonObject(key, button = null) {
if (button == null) {
- button = {};
- button['favicon'] = 'none';
- button['title'] = '';
- button['url'] = '';
- button['icon'] = 'globe';
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop('none');
+ this.buttons[key].title = m.prop('');
+ this.buttons[key].url = m.prop('');
+ this.buttons[key].icon = m.prop('globe');
+ } else {
+ this.buttons[key] = {};
+ this.buttons[key].index = m.prop(key);
+ this.buttons[key].favicon = m.prop(button.favicon);
+ this.buttons[key].title = m.prop(button.title);
+ this.buttons[key].url = m.prop(button.url);
+ this.buttons[key].icon = m.prop(button.icon);
}
- this.buttons[key] = {};
- this.buttons[key].index = m.prop(key);
- this.buttons[key].favicon = m.prop(button["favicon"]);
- this.buttons[key].title = m.prop(button["title"]);
- this.buttons[key].url = m.prop(button["url"]);
- this.buttons[key].icon = m.prop(button["icon"]);
}
-}
\ No newline at end of file
+}
diff --git a/js/forum/src/components/WebsiteInputComponent.js b/js/forum/src/components/WebsiteInputComponent.js
index d92df8c..5908067 100644
--- a/js/forum/src/components/WebsiteInputComponent.js
+++ b/js/forum/src/components/WebsiteInputComponent.js
@@ -1,49 +1,49 @@
import Component from 'flarum/Component';
-import extract from 'flarum/utils/extract';
import IconSelectorComponent from 'Davis/SocialProfile/components/IconSelectorComponent';
-
+
export default class WebsiteInputComponent extends Component {
- init(){
+ init() {
super.init();
-
+
this.button = this.props.button;
}
-
+
view() {
-
- return (
-
-
-
- {IconSelectorComponent.component({
- selection: this.button.icon,
- favicon: this.button.favicon,
- index: this.button.index
- })}
- {
- this.button.url(value);
- clearTimeout(this.waittilfinsihed);
- if(this.button.icon() !== 'fa-circle-o-notch fa-spin') {
- this.button.icon('fa-circle-o-notch fa-spin');
- this.button.favicon('none');
- }
- this.waittilfinsihed = setTimeout(() => {
- var urlpattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/;
- if(urlpattern.test(this.button.url().toLowerCase())) {
- var iconurl = (this.button.url().replace(/(:\/\/[^\/]+).*$/, '$1') + '/favicon.ico');
+ return m('div', {
+ className: 'Form-group form-group-social',
+ id: `socialgroup-${this.button.index()}`,
+ }, [
+ m('input', {
+ className: 'SocialFormControl SocialTitle',
+ placeholder: app.translator.trans('davis-socialprofile.forum.edit.title'),
+ tabIndex: ((this.button.index() + 1) * 2) - 1,
+ value: this.button.title(),
+ onchange: m.withAttr('value', this.button.title),
+ }),
+ IconSelectorComponent.component({
+ selection: this.button.icon,
+ favicon: this.button.favicon,
+ index: this.button.index,
+ }),
+ m('input', {
+ className: 'SocialFormControl Socialurl',
+ placeholder: app.translator.trans('davis-socialprofile.forum.edit.url'),
+ tabIndex: ((this.button.index() + 1) * 2),
+ value: this.button.url(),
+ onchange: m.withAttr('value', (value) => {
+ this.button.url(value);
+ clearTimeout(this.waittilfinsihed);
+ if (this.button.icon() !== 'fa-circle-o-notch fa-spin') {
+ this.button.icon('fa-circle-o-notch fa-spin');
+ this.button.favicon('none');
+ }
+ this.waittilfinsihed = setTimeout(() => {
+ const urlpattern =
+ /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/;
+
+ if (urlpattern.test(this.button.url().toLowerCase())) {
+ const iconurl = (`${this.button.url().replace(/(:\/\/[^\/]+).*$/, '$1')}
+ /favicon.ico`);
this.button.favicon(iconurl);
this.button.icon('favicon');
m.redraw();
@@ -52,26 +52,23 @@ export default class WebsiteInputComponent extends Component {
this.button.favicon('none');
m.redraw();
}
- }, 1000);
- })}
- >
-
-
-
- );
+ }, 1000);
+ }),
+ }),
+ m('input', {
+ className: 'SocialFormControl SocialIcon',
+ id: `icon${this.button.index()}`,
+ style: { display: 'none' },
+ value: this.button.icon(),
+ onchange: m.withAttr('value', this.button.icon),
+ }),
+ m('input', {
+ className: 'SocialFormControl Socialfavicon',
+ id: `favicon${this.button.index()}`,
+ style: { display: 'none' },
+ value: this.button.favicon(),
+ onchange: m.withAttr('value', this.button.favicon),
+ }),
+ ]);
}
-}
\ No newline at end of file
+}
diff --git a/js/forum/src/main.js b/js/forum/src/main.js
index 48a7916..58976f6 100644
--- a/js/forum/src/main.js
+++ b/js/forum/src/main.js
@@ -1,112 +1,89 @@
import app from 'flarum/app';
+import Model from 'flarum/Model';
+import User from 'flarum/models/User';
import { extend } from 'flarum/extend';
import UserCard from 'flarum/components/UserCard';
import Badge from 'flarum/components/Badge';
import SocialButtonsModal from 'Davis/SocialProfile/components/SocialButtonsModal';
+import DeleteButtonModal from 'Davis/SocialProfile/components/DeleteButtonModal';
-app.initializers.add('davis-socialprofile-forum', function() {
+app.initializers.add('davis-socialprofile-forum', () => {
+ User.prototype.socialButtons = Model.attribute('socialButtons');
- extend(UserCard.prototype, 'init', function() {
- var user = this.props.user;
- var apiUrl = app.forum.attribute('apiUrl') + '/profile/socialbutton/' + user.data.id;
- this.buttonsArray = null; //Indicate we haven't retrieved the user's buttons
- //Get buttons from database
- app.request({method: "GET", url: apiUrl}).then(result => {
- //Test if user has set their buttons up already
- if(result.data.attributes.hasOwnProperty("buttons")) {
- //Test if buttons have been set up, but the array is empty
- if (result.data.attributes.buttons == "[]") {
- //Since there are no buttons set, we have a blank slate
- this.buttonsArray = true; //Indicate we have retrieved the user's buttons
- this.isBlankSlate = true; //Indicate we don't have any buttons
+ extend(UserCard.prototype, 'init', function () {
+ $('#app').on('refreshSocialButtons', (e, buttons) => {
+ this.buttons = JSON.parse(buttons || '[]');
+ this.props.user.data.attributes.socialButtons = JSON.parse(buttons || '[]');
+ this.props.user.freshness = new Date();
+ m.redraw();
+ });
+ });
+
+ extend(UserCard.prototype, 'infoItems', function (items) {
+ this.isSelf = (app.session.user === this.props.user);
+ this.canEdit = app.session.user ? app.session.user.data.attributes.canEdit : false;
+ this.buttons = JSON.parse(this.props.user.data.attributes.socialButtons || '[]');
+
+ if (this.buttons.length) {
+ this.buttons.forEach((button, index) => {
+ if (button.title !== '' && button.icon !== '' && button.url !== '') {
+ let buttonStyle = '';
+ let buttonClassName = '';
+
+ if (button.icon === 'favicon' || button.icon === 'favicon-grey') {
+ buttonStyle = `background-image: url("${button.favicon}");background-size: 60%;background-position: 50% 50%;background-repeat: no-repeat;`;
+ if (button.icon === 'favicon-grey') {
+ buttonClassName = `${button.icon}-${index} social-button social-greyscale-button`;
} else {
- //The buttons array must not be empty, so lets set it
- this.buttonsArray = JSON.parse(result.data.attributes.buttons);
- this.isBlankSlate = false; //Indicate we do have buttons
+ buttonClassName = `${button.icon}-${index} social-button`;
}
- } else {
- //This user has never set their buttons
- this.buttonsArray = true; //Indicate we have retrieved the user's buttons
- this.isBlankSlate = true; //Indicate we don't have any buttons
+ } else {
+ buttonStyle = '';
+ buttonClassName = `${button.icon}-${index} social-button`;
+ }
+ items.add(`${buttonClassName}${this.deleting ? ' social-button--highlightable' : ''}`, Badge.component({
+ type: `social social-icon-${index}`,
+ icon: button.icon.replace('fa-', ''),
+ label: button.title,
+ style: buttonStyle,
+ onclick: () => {
+ if (this.deleting) {
+ app.modal.show(new DeleteButtonModal({ user: this.props.user, index }));
+ } else {
+ window.open(button.url, '_blank');
+ }
+ },
+ }));
}
- user.freshness = new Date(); //Tell Mithril we have new data
- m.redraw(); //Refresh the DOM
});
-
- //If the buttons have been edited, we need to refresh them
- $('#app').on('refreshSocialButtons', (e, buttons)=>{
- var user = this.props.user; //Then is our user
- this.buttonsArray = JSON.parse(buttons); //Parse the saved array from editing
- this.isBlankSlate = false; //Indicate we do really have buttons
- user.freshness = new Date(); //Tell Mithril we have new data
- m.redraw(); //Refresh DOM
- });
- });
-
- extend(UserCard.prototype, 'infoItems', function(items) {
-
- // If request hasn't loaded yet, don't add any items.
- if (!this.buttonsArray) return;
-
- //If there are buttons, add them
- if (!this.isBlankSlate) {
- //Loop through the buttonsArray
- for (const k in this.buttonsArray) {
- const selectedButton = this.buttonsArray[k]; //Set constant for easier selection
- //Ensure the button has a title, icon, and url
- if (selectedButton["title"] !== "" && selectedButton["icon"] !== "" && selectedButton["url"] !== "") {
- var buttonStyle, buttonClass;
- //If the button is using a favicon, make sure it is displayed
- if (selectedButton['icon'] == 'favicon' || selectedButton['icon'] == 'favicon-grey') {
- buttonStyle = 'background-image: url("'+selectedButton['favicon']+'");background-size: 60%;background-position: 50% 50%;background-repeat: no-repeat;';
- //If the favicon is set to greyscale, make sure it is displayed
- if (selectedButton['icon'] == 'favicon-grey') {
- buttonClass = selectedButton["icon"] + '-' + k + ' social-button social-greyscale-button';
- } else {
- buttonClass = selectedButton["icon"] + '-' + k + ' social-button';
- }
- } else {
- buttonStyle = '';
- buttonClass = selectedButton["icon"] + '-' + k + ' social-button';
- }
- //Acctually add the button
- items.add(buttonClass , Badge.component({
- type: "social social-icon-" + k,
- icon: selectedButton["icon"].replace('fa-', ''),
- label: selectedButton["title"],
- style: buttonStyle,
- onclick: function() {
- window.open(selectedButton["url"],'_blank');
- }
- }));
- }
- }
- //Add the edit buttons at the end, as long as it's their own profile
- if (app.session.user === app.current.user && app.session.user !== undefined && app.current.user !== undefined) {
- //Add the settings button
- items.add('settings social-button', Badge.component({
- type: "social social-settings",
- icon: 'cog',
- label: app.translator.trans('davis-socialprofile.forum.edit.edit'),
- onclick: () => {
- app.modal.show(new SocialButtonsModal({data: this.buttonsArray})); //Show the edit modal
- }
- }), -1);
- }
- //It turns out they don't have any buttons
- } else {
- //Add an add button only if its their own profile
- if (app.session.user === app.current.user && app.session.user !== undefined && app.current.user !== undefined) {
- //Add the add button
- items.add('settings social-button', Badge.component({
- type: "social null-social-settings",
- icon: "plus",
- label: app.translator.trans('davis-socialprofile.forum.edit.add'),
- onclick: () => {
- app.modal.show(new SocialButtonsModal({data: this.buttonsArray}));
- }
- }), -1);
- }
- }
- });
-});
\ No newline at end of file
+ if (this.isSelf) {
+ items.add('settings social-button', Badge.component({
+ type: 'social social-settings',
+ icon: 'cog',
+ label: app.translator.trans('davis-socialprofile.forum.edit.edit'),
+ onclick: () => {
+ app.modal.show(new SocialButtonsModal({ user: this.props.user }));
+ },
+ }), -1);
+ } else if (this.canEdit) {
+ items.add('settings social-button', Badge.component({
+ type: `social social-moderate ${this.deleting ? 'social-moderate--highlighted' : ''}`,
+ icon: 'exclamation-triangle',
+ label: app.translator.trans('davis-socialprofile.forum.edit.delete'),
+ onclick: () => {
+ this.deleting = !this.deleting;
+ },
+ }), -1);
+ }
+ } else if (this.isSelf) {
+ items.add('settings social-button', Badge.component({
+ type: 'social null-social-settings',
+ icon: 'plus',
+ label: app.translator.trans('davis-socialprofile.forum.edit.add'),
+ onclick: () => {
+ app.modal.show(new SocialButtonsModal({ user: this.props.user }));
+ },
+ }), -1);
+ }
+ });
+});
diff --git a/less/forum/extension.less b/less/forum/extension.less
index fa53242..f728a02 100644
--- a/less/forum/extension.less
+++ b/less/forum/extension.less
@@ -27,7 +27,7 @@
border-radius: 3px;
font-size: 14px;
box-shadow: 0 0 0 1px #ddd;
- color: inherit;
+ color: #111;
}
.iconpicker-item-invt {
float: left;
@@ -62,7 +62,7 @@
top: 100% !important;
overflow: auto;
max-height: 45vh !important;
- min-width: 189px !important;
+ min-width: 190px !important;
z-index: 2055;
float: left;
background-color: #fff;
@@ -91,8 +91,13 @@
-webkit-appearance: none;
}
.Socialurl {
- margin-left: 1%;
- width: 82.5%;
+ margin-left: 3px;
+ width: 260px;
+}
+@media (max-width: 767px) {
+ .Socialurl {
+ width: 293px;
+ }
}
.social-greyscale-button {
-webkit-filter: grayscale(1) contrast(2) brightness(2);
@@ -104,6 +109,17 @@
.icondropdown > button > i {
display: inline-block !important;
}
+.social-moderate--highlighted > .Badge-icon {
+ color: #F22613;
+ transition: .5s;
+ font-size: 23px;
+ -webkit-animation: fa-spin 2s infinite linear;
+ animation: fa-spin 2s infinite linear;
+}
+.social-button--highlightable:hover {
+ border-radius: 4px;
+ background: #F22613;
+}
.fa-spin {
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear;
diff --git a/locale/en.yml b/locale/en.yml
index d5b5966..37d855b 100644
--- a/locale/en.yml
+++ b/locale/en.yml
@@ -7,5 +7,7 @@ davis-socialprofile:
title: "Title"
url: "Url"
submit: "Save"
+ delete: "Delete"
+ deletetitle: "Delete Button"
admin:
test: "Test"
diff --git a/locale/fr.yml b/locale/fr.yml
index 73c726a..e1b37b5 100644
--- a/locale/fr.yml
+++ b/locale/fr.yml
@@ -7,5 +7,5 @@ davis-socialprofile:
title: "Titre"
url: "Url"
submit: "Sauvegarder"
- admin:
- test: "Test"
+ delete: "Effacer"
+ deletetitle: "Bouton Supprimer"
diff --git a/locale/ru.yml b/locale/ru.yml
index 74bcb2d..f4ae224 100644
--- a/locale/ru.yml
+++ b/locale/ru.yml
@@ -7,5 +7,5 @@ davis-socialprofile:
title: "Надпись"
url: "Url"
submit: "Сохранить"
- admin:
- test: "Test"
+ delete: "Удалить"
+ deletetitle: "кнопка удаления"
diff --git a/migrations/2016_01_14_000000_create_socialbuttons_table.php b/migrations/2016_01_14_000000_create_socialbuttons_table.php
index 0828c94..fe2194c 100644
--- a/migrations/2016_01_14_000000_create_socialbuttons_table.php
+++ b/migrations/2016_01_14_000000_create_socialbuttons_table.php
@@ -8,8 +8,6 @@
* For the full copyright and license information, please view the MIT license
*/
-namespace Davis\SocialProfile\Migration;
-
use Flarum\Database\Migration;
use Illuminate\Database\Schema\Blueprint;
diff --git a/src/Buttons.php b/migrations/2016_10_20_000000_create_socialbuttons_column.php
similarity index 56%
rename from src/Buttons.php
rename to migrations/2016_10_20_000000_create_socialbuttons_column.php
index fb94e0c..1144573 100644
--- a/src/Buttons.php
+++ b/migrations/2016_10_20_000000_create_socialbuttons_column.php
@@ -1,18 +1,15 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile;
-
-use Flarum\Database\AbstractModel;
-
-class Buttons extends AbstractModel
-{
- protected $table = 'socialbuttons';
-}
+
+ *
+ * For the full copyright and license information, please view the MIT license
+ */
+
+use Flarum\Database\Migration;
+
+return Migration::addColumns('users', [
+ 'social_buttons' => ['longText', 'nullable' => true],
+]);
diff --git a/migrations/2016_10_21_000000_migrate_data_to_user_column.php b/migrations/2016_10_21_000000_migrate_data_to_user_column.php
new file mode 100644
index 0000000..f16dec4
--- /dev/null
+++ b/migrations/2016_10_21_000000_migrate_data_to_user_column.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the MIT license
+ */
+
+use Illuminate\Database\ConnectionInterface;
+
+return [
+ 'up' => function (ConnectionInterface $db) {
+ $results = $db->table('socialbuttons')->get();
+ foreach ($results as $result) {
+ $db->table('users')
+ ->where('id', $result->user_id)
+ ->update(['social_buttons' => $result->buttons]);
+ }
+ },
+ 'down' => function (ConnectionInterface $db) {
+ $results = $db->table('users')->select('social_buttons')->get();
+ foreach ($results as $result) {
+ $db->table('socialbuttons')->insert(
+ ['user_id' => $result->id, 'buttons' => $result->social_buttons]
+ );
+ }
+ },
+];
diff --git a/migrations/2016_10_22_000000_drop_socialbuttons_table.php b/migrations/2016_10_22_000000_drop_socialbuttons_table.php
new file mode 100644
index 0000000..64ec34b
--- /dev/null
+++ b/migrations/2016_10_22_000000_drop_socialbuttons_table.php
@@ -0,0 +1,25 @@
+
+ *
+ * For the full copyright and license information, please view the MIT license
+ */
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Schema\Builder;
+
+return [
+ 'up' => function (Builder $schema) {
+ $schema->drop('socialbuttons');
+ },
+ 'down' => function (Builder $schema) {
+ $schema->create('socialbuttons', function (Blueprint $table) {
+ $table->increments('id');
+ $table->integer('user_id')->unsigned();
+ $table->longText('buttons');
+ });
+ },
+];
diff --git a/src/Api/Controllers/EditSocialButtonsController.php b/src/Api/Controllers/EditSocialButtonsController.php
deleted file mode 100644
index a5e71af..0000000
--- a/src/Api/Controllers/EditSocialButtonsController.php
+++ /dev/null
@@ -1,40 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Api\Controllers;
-
-use Davis\SocialProfile\Api\Serializers\SocialButtonsSerializer;
-use Davis\SocialProfile\Commands\SaveSocialSettings;
-use Flarum\Api\Controller\AbstractResourceController;
-use Illuminate\Contracts\Bus\Dispatcher;
-use Psr\Http\Message\ServerRequestInterface;
-use Tobscure\JsonApi\Document;
-
-class EditSocialButtonsController extends AbstractResourceController
-{
- public $serializer = SocialButtonsSerializer::class;
-
- protected $bus;
-
- public function __construct(Dispatcher $bus)
- {
- $this->bus = $bus;
- }
-
- protected function data(ServerRequestInterface $request, Document $document)
- {
- $actor = $request->getAttribute('actor');
- $Buttons = array_get($request->getParsedBody(), 'buttons');
-
- return $this->bus->dispatch(
- new SaveSocialSettings($Buttons, $actor)
- );
- }
-}
diff --git a/src/Api/Controllers/GetSocialButtonsController.php b/src/Api/Controllers/GetSocialButtonsController.php
deleted file mode 100644
index 2c749e4..0000000
--- a/src/Api/Controllers/GetSocialButtonsController.php
+++ /dev/null
@@ -1,35 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Api\Controllers;
-
-use Davis\SocialProfile\Repository\UserSocialRepository;
-use Flarum\Api\Controller\AbstractResourceController;
-use Psr\Http\Message\ServerRequestInterface;
-use Tobscure\JsonApi\Document;
-
-class GetSocialButtonsController extends AbstractResourceController
-{
- public $serializer = 'Davis\SocialProfile\Api\Serializers\GetSocialButtonsSerializer';
-
- public function __construct(UserSocialRepository $users)
- {
- $this->users = $users;
- }
-
- protected function data(ServerRequestInterface $request, Document $document)
- {
- $id = array_get($request->getQueryParams(), 'user');
-
- $actor = $request->getAttribute('actor');
-
- return $this->users->findOrFail($id, $actor);
- }
-}
diff --git a/src/Api/Serializers/GetSocialButtonsSerializer.php b/src/Api/Serializers/GetSocialButtonsSerializer.php
deleted file mode 100644
index 4d7aa05..0000000
--- a/src/Api/Serializers/GetSocialButtonsSerializer.php
+++ /dev/null
@@ -1,35 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Api\Serializers;
-
-use Flarum\Api\Serializer\UserBasicSerializer;
-use Flarum\Core\Access\Gate;
-
-class GetSocialButtonsSerializer extends UserBasicSerializer
-{
- protected $gate;
-
- public function __construct(Gate $gate)
- {
- $this->gate = $gate;
- }
-
- protected function getDefaultAttributes($user)
- {
- $gate = $this->gate->forUser($this->actor);
-
- $attributes = [
- 'buttons' => $user->buttons,
- ];
-
- return $attributes;
- }
-}
diff --git a/src/Api/Serializers/SocialButtonsSerializer.php b/src/Api/Serializers/SocialButtonsSerializer.php
deleted file mode 100644
index 4c2f8f5..0000000
--- a/src/Api/Serializers/SocialButtonsSerializer.php
+++ /dev/null
@@ -1,25 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Api\Serializers;
-
-use Flarum\Api\Serializer\AbstractSerializer;
-
-class SocialButtonsSerializer extends AbstractSerializer
-{
- //protected $type = 'images';
-
- protected function getDefaultAttributes($model)
- {
- return [
- //
- ];
- }
-}
diff --git a/src/Commands/SaveSocialSettings.php b/src/Commands/SaveSocialSettings.php
deleted file mode 100644
index b74fc5d..0000000
--- a/src/Commands/SaveSocialSettings.php
+++ /dev/null
@@ -1,26 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Commands;
-
-use Flarum\Core\User;
-
-class SaveSocialSettings
-{
- public $Buttons;
-
- public $actor;
-
- public function __construct($Buttons, User $actor)
- {
- $this->Buttons = $Buttons;
- $this->actor = $actor;
- }
-}
diff --git a/src/Commands/SaveSocialSettingsHandler.php b/src/Commands/SaveSocialSettingsHandler.php
deleted file mode 100644
index a047369..0000000
--- a/src/Commands/SaveSocialSettingsHandler.php
+++ /dev/null
@@ -1,58 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Commands;
-
-use Davis\SocialProfile\Buttons;
-use Davis\SocialProfile\Events\SocialProfileEditted;
-use Flarum\Core\Access\AssertPermissionTrait;
-use Flarum\Core\Repository\UserRepository;
-use Flarum\Core\Support\DispatchEventsTrait;
-use Flarum\Foundation\Application;
-use Illuminate\Events\Dispatcher;
-
-class SaveSocialSettingsHandler
-{
- use DispatchEventsTrait;
- use AssertPermissionTrait;
-
- protected $users;
-
- protected $app;
-
- public function __construct(
- Dispatcher $events,
- UserRepository $users,
- Application $app
- ) {
- $this->events = $events;
- $this->users = $users;
- $this->app = $app;
- }
-
- public function handle(SaveSocialSettings $command)
- {
- if (Buttons::where('user_id', $command->actor->id)->exists()) {
- $Buttons = Buttons::where('user_id', $command->actor->id)->first();
- } else {
- $Buttons = new Buttons;
- }
- $Buttons->user_id = $command->actor->id;
- $Buttons->Buttons = $command->Buttons;
-
- $this->events->fire(
- new SocialProfileEditted($command->actor, $command->Buttons)
- );
-
- $Buttons->save();
-
- return $Buttons;
- }
-}
diff --git a/src/Events/SocialProfileEditted.php b/src/Events/UserButtonsWereChanged.php
similarity index 51%
rename from src/Events/SocialProfileEditted.php
rename to src/Events/UserButtonsWereChanged.php
index b0a85f8..04a882d 100644
--- a/src/Events/SocialProfileEditted.php
+++ b/src/Events/UserButtonsWereChanged.php
@@ -1,27 +1,36 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Events;
-
-use Davis\SocialProfile\Buttons;
-use Flarum\Core\User;
-
-class SocialProfileEditted
-{
- public $actor;
-
- public $Buttons;
-
- public function __construct(User $actor, $Buttons)
- {
- $this->actor = $actor;
- $this->Buttons = $Buttons;
- }
-}
+
+ *
+ * For the full copyright and license information, please view the MIT license
+ */
+
+namespace Davis\SocialProfile\Events;
+
+use Flarum\Core\User;
+
+class UserButtonsWereChanged
+{
+ /**
+ * @var User
+ */
+ public $user;
+
+ /**
+ * @var User
+ */
+ public $actor;
+
+ /**
+ * @param User $user
+ * @param User $actor
+ */
+ public function __construct(User $user, User $actor = null)
+ {
+ $this->user = $user;
+ $this->actor = $actor;
+ }
+}
diff --git a/src/Listeners/AddApiAttributes.php b/src/Listeners/AddApiAttributes.php
deleted file mode 100755
index 899bfe9..0000000
--- a/src/Listeners/AddApiAttributes.php
+++ /dev/null
@@ -1,30 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Listeners;
-
-use Davis\SocialProfile\Api\Controllers\EditSocialButtonsController;
-use Davis\SocialProfile\Api\Controllers\GetSocialButtonsController;
-use Flarum\Event\ConfigureApiRoutes;
-use Illuminate\Events\Dispatcher;
-
-class AddApiAttributes
-{
- public function subscribe(Dispatcher $events)
- {
- $events->listen(ConfigureApiRoutes::class, [$this, 'configureApiRoutes']);
- }
-
- public function configureApiRoutes(ConfigureApiRoutes $event)
- {
- $event->post('/profile/socialbuttons', 'davis.profile.buttons', EditSocialButtonsController::class);
- $event->get('/profile/socialbutton/{user}', 'davis.profile.button.user', GetSocialButtonsController::class);
- }
-}
diff --git a/src/Listeners/AddClientAssets.php b/src/Listeners/AddClientAssets.php
index 1193f4c..30ec9b7 100644
--- a/src/Listeners/AddClientAssets.php
+++ b/src/Listeners/AddClientAssets.php
@@ -3,7 +3,7 @@
/*
* This file is part of davis/flarum-ext-socialprofile
*
- * (c) Connor Davis
+ * © Connor Davis
*
* For the full copyright and license information, please view the MIT license
*/
@@ -27,15 +27,15 @@ public function addAssets(ConfigureClientView $event)
{
if ($event->isForum()) {
$event->addAssets([
- __DIR__.'/../../js/forum/dist/extension.js',
- __DIR__.'/../../less/forum/extension.less'
+ __DIR__ . '/../../js/forum/dist/extension.js',
+ __DIR__ . '/../../less/forum/extension.less',
]);
$event->addBootstrapper('Davis/SocialProfile/main');
}
if ($event->isAdmin()) {
$event->addAssets([
- __DIR__.'/../../js/admin/dist/extension.js'
+ __DIR__ . '/../../js/admin/dist/extension.js',
]);
$event->addBootstrapper('Davis/SocialProfile/main');
}
@@ -43,9 +43,9 @@ public function addAssets(ConfigureClientView $event)
public function addLocales(ConfigureLocales $event)
{
- foreach (new DirectoryIterator(__DIR__.'/../../locale') as $file) {
+ foreach (new DirectoryIterator(__DIR__ . '/../../locale') as $file) {
if ($file->isFile() && in_array($file->getExtension(), ['yml', 'yaml'])) {
- $event->locales->addTranslations($file->getBasename('.'.$file->getExtension()), $file->getPathname());
+ $event->locales->addTranslations($file->getBasename('.' . $file->getExtension()), $file->getPathname());
}
}
}
diff --git a/src/Listeners/AddUserProfileAttributes.php b/src/Listeners/AddUserProfileAttributes.php
new file mode 100644
index 0000000..aea7b5a
--- /dev/null
+++ b/src/Listeners/AddUserProfileAttributes.php
@@ -0,0 +1,36 @@
+
+ *
+ * For the full copyright and license information, please view the MIT license
+ */
+
+namespace Davis\SocialProfile\Listeners;
+
+use Flarum\Api\Serializer\UserSerializer;
+use Flarum\Event\PrepareApiAttributes;
+use Illuminate\Contracts\Events\Dispatcher;
+
+class AddUserProfileAttributes
+{
+ /**
+ * @param Dispatcher $events
+ */
+ public function subscribe(Dispatcher $events)
+ {
+ $events->listen(PrepareApiAttributes::class, [$this, 'addApiAttributes']);
+ }
+
+ /**
+ * @param PrepareApiAttributes $event
+ */
+ public function addApiAttributes(PrepareApiAttributes $event)
+ {
+ if ($event->isSerializer(UserSerializer::class)) {
+ $event->attributes['socialButtons'] = $event->model->social_buttons;
+ }
+ }
+}
diff --git a/src/Listeners/LoadSettingsFromDatabase.php b/src/Listeners/LoadSettingsFromDatabase.php
index 7e9e188..801f9ec 100644
--- a/src/Listeners/LoadSettingsFromDatabase.php
+++ b/src/Listeners/LoadSettingsFromDatabase.php
@@ -3,7 +3,7 @@
/*
* This file is part of davis/flarum-ext-socialprofile
*
- * (c) Connor Davis
+ * © Connor Davis
*
* For the full copyright and license information, please view the MIT license
*/
@@ -20,7 +20,7 @@ class LoadSettingsFromDatabase
protected $packagePrefix = 'davis.socialprofile.';
protected $fieldsToGet = [
- 'test',
+ 'test',
];
protected $settings;
@@ -39,7 +39,7 @@ public function prepareApiAttributes(PrepareApiAttributes $event)
{
if ($event->isSerializer(ForumSerializer::class)) {
foreach ($this->fieldsToGet as $field) {
- $event->attributes[$this->packagePrefix.$field] = $this->settings->get($this->packagePrefix.$field);
+ $event->attributes[$this->packagePrefix . $field] = $this->settings->get($this->packagePrefix . $field);
}
}
}
diff --git a/src/Listeners/UpdateProfileInDatabase.php b/src/Listeners/UpdateProfileInDatabase.php
new file mode 100644
index 0000000..2f17ea1
--- /dev/null
+++ b/src/Listeners/UpdateProfileInDatabase.php
@@ -0,0 +1,101 @@
+
+ *
+ * For the full copyright and license information, please view the MIT license
+ */
+
+namespace Davis\SocialProfile\Listeners;
+
+use Davis\SocialProfile\Events\UserButtonsWereChanged;
+use Davis\SocialProfile\ProfileValidator;
+use Flarum\Core\Access\AssertPermissionTrait;
+use Flarum\Event\UserWillBeSaved;
+use Illuminate\Contracts\Events\Dispatcher;
+
+class UpdateProfileInDatabase
+{
+ use AssertPermissionTrait;
+
+ /**
+ * Validator for limited suspension.
+ *
+ * @var SuspendValidator
+ */
+ protected $validator;
+
+ /**
+ * @param SuspendValidator $validator
+ */
+ public function __construct(ProfileValidator $validator)
+ {
+ $this->validator = $validator;
+ }
+
+ /**
+ * @param Dispatcher $events
+ */
+ public function subscribe(Dispatcher $events)
+ {
+ $events->listen(UserWillBeSaved::class, [$this, 'whenUserWillBeSaved']);
+ }
+
+ /**
+ * @param UserWillBeSaved $event
+ */
+ public function whenUserWillBeSaved(UserWillBeSaved $event)
+ {
+ $attributes = array_get($event->data, 'attributes', []);
+
+ if (array_key_exists('socialButtons', $attributes)) {
+ $this->validator->assertValid($attributes);
+
+ $user = $event->user;
+ $actor = $event->actor;
+
+ if ($actor->id !== $user->id) {
+ $this->assertPermission(
+ $this->elementsOnlyRemoved(
+ $user->social_buttons,
+ $attributes['socialButtons']
+ )
+ );
+ $this->assertCan($actor, 'edit', $user);
+ }
+
+ $user->social_buttons = $attributes['socialButtons'];
+ $user->raise(new UserButtonsWereChanged($user));
+ }
+ }
+
+ protected function elementsOnlyRemoved($current, $proposed)
+ {
+ $current = json_decode($current);
+ $proposed = json_decode($proposed);
+
+ foreach ($proposed as $component) {
+ if (!$this->hasMatchingComponent($current, $component)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected function hasMatchingComponent($array, $component)
+ {
+ $foundMatch = false;
+
+ foreach ($array as $test) {
+ if ($component == $test) {
+ $foundMatch = true;
+ break;
+ }
+ }
+
+ return $foundMatch;
+ }
+}
diff --git a/src/ProfileValidator.php b/src/ProfileValidator.php
new file mode 100644
index 0000000..47f0ade
--- /dev/null
+++ b/src/ProfileValidator.php
@@ -0,0 +1,88 @@
+
+ *
+ * For the full copyright and license information, please view the MIT license
+ */
+
+namespace Davis\SocialProfile;
+
+use Flarum\Core\Validator\AbstractValidator;
+use Flarum\Event\ConfigureValidator;
+
+class ProfileValidator extends AbstractValidator
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected $rules = [
+ 'socialButtons' => ['json', 'socialbuttons'],
+ 'title' => ['string', 'max:55', 'required'],
+ 'url' => ['url', 'max:120', 'required'],
+ 'icon' => ['string', 'max:15', 'required'],
+ 'favicon' => ['string', 'max:120', 'required'],
+ ];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getMessages()
+ {
+ return [
+ 'socialButtons.socialbuttons' => 'The data you sent is missing required variables.',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function makeValidator(array $attributes)
+ {
+ $rules = array_only($this->getRules(), array_keys($attributes));
+
+ $this->validator->extend('socialbuttons', function ($attribute, $value, $parameters, $validator) {
+ return $this->validateSocialButtons($attribute, $value, $parameters, $validator);
+ });
+ $validator = $this->validator->make($attributes, $rules, $this->getMessages());
+
+ $this->events->fire(
+ new ConfigureValidator($this, $validator)
+ );
+
+ return $validator;
+ }
+
+ protected function validateSocialButtons($attribute, $value, $parameters, $validator)
+ {
+ if ($value != '[]') {
+ $data = json_decode($value);
+
+ foreach ($data as $button) {
+ if (!isset($button->title)) {
+ return false;
+ } else if (!isset($button->url)) {
+ return false;
+ } else if (!isset($button->icon)) {
+ return false;
+ } else if (!isset($button->favicon)) {
+ return false;
+ } else {
+ $attributes = [
+ 'title' => $button->title,
+ 'url' => $button->url,
+ 'icon' => $button->icon,
+ 'favicon' => $button->favicon,
+ ];
+ $this->assertValid($attributes);
+
+ return true;
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+}
diff --git a/src/Repository/UserSocialRepository.php b/src/Repository/UserSocialRepository.php
deleted file mode 100644
index e6b03ed..0000000
--- a/src/Repository/UserSocialRepository.php
+++ /dev/null
@@ -1,26 +0,0 @@
-
- *
- * For the full copyright and license information, please view the MIT license
- */
-
-namespace Davis\SocialProfile\Repository;
-
-use Davis\SocialProfile\Buttons;
-
-class UserSocialRepository
-{
- public function query()
- {
- return Buttons::query();
- }
-
- public function findOrFail($id)
- {
- return Buttons::where('user_id', $id)->first();
- }
-}