diff --git a/dev/Common/Plugins.js b/dev/Common/Plugins.js index fbb9f34bf..1829ccfff 100644 --- a/dev/Common/Plugins.js +++ b/dev/Common/Plugins.js @@ -16,8 +16,10 @@ function Plugins() { this.oSettings = require('Storage/Settings'); - this.oViewModelsHooks = {}; this.oSimpleHooks = {}; + + this.aUserViewModelsHooks = []; + this.aAdminViewModelsHooks = []; } /** @@ -26,9 +28,14 @@ Plugins.prototype.oSettings = {}; /** - * @type {Object} + * @type {Array} */ - Plugins.prototype.oViewModelsHooks = {}; + Plugins.prototype.aUserViewModelsHooks = []; + + /** + * @type {Array} + */ + Plugins.prototype.aAdminViewModelsHooks = []; /** * @type {Object} @@ -82,17 +89,44 @@ * @param {string} sAction * @param {Object=} oParameters * @param {?number=} iTimeout - * @param {string=} sGetAdd = '' - * @param {Array=} aAbortActions = [] */ - Plugins.prototype.remoteRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions) + Plugins.prototype.remoteRequest = function (fCallback, sAction, oParameters, iTimeout) { if (Globals.__APP__) { - Globals.__APP__.remote().defaultRequest(fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions); + Globals.__APP__.remote().defaultRequest(fCallback, 'Plugin' + sAction, oParameters, iTimeout); } }; + /** + * @param {Function} SettingsViewModelClass + * @param {string} sLabelName + * @param {string} sTemplate + * @param {string} sRoute + */ + Plugins.prototype.addSettingsViewModel = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute) + { + this.aViewModelsHooks.push([SettingsViewModelClass, sTemplate, sLabelName, sRoute]); + }; + + /** + * @param {Function} SettingsViewModelClass + * @param {string} sLabelName + * @param {string} sTemplate + * @param {string} sRoute + */ + Plugins.prototype.addSettingsViewModelForAdmin = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute) + { + this.aAdminViewModelsHooks.push([SettingsViewModelClass, sTemplate, sLabelName, sRoute]); + }; + + Plugins.prototype.runSettingsViewModelHooks = function (bAdmin) + { + _.each(bAdmin ? this.aAdminViewModelsHooks : this.aViewModelsHooks, function (aView) { + require('Knoin/Knoin').addSettingsViewModel(aView[0], aView[1], aView[2], aView[3]); + }); + }; + /** * @param {string} sPluginSection * @param {string} sName diff --git a/dev/Screen/Admin/Settings.js b/dev/Screen/Admin/Settings.js index 44e114aa6..74ccb0851 100644 --- a/dev/Screen/Admin/Settings.js +++ b/dev/Screen/Admin/Settings.js @@ -8,6 +8,8 @@ kn = require('Knoin/Knoin'), + Plugins = require('Common/Plugins'), + AbstractSettings = require('Screen/AbstractSettings') ; @@ -63,6 +65,8 @@ kn.addSettingsViewModel(require('Settings/Admin/About'), 'AdminSettingsAbout', 'About', 'about'); + Plugins.runSettingsViewModelHooks(true); + if (fCallback) { fCallback(); diff --git a/dev/Screen/User/Settings.js b/dev/Screen/User/Settings.js index 0f80ee3cb..50bf00084 100644 --- a/dev/Screen/User/Settings.js +++ b/dev/Screen/User/Settings.js @@ -10,6 +10,8 @@ Globals = require('Common/Globals'), Translator = require('Common/Translator'), + Plugins = require('Common/Plugins'), + AppStore = require('Stores/User/App'), Settings = require('Storage/Settings'), @@ -101,6 +103,8 @@ 'SettingsOpenPGP', 'SETTINGS_LABELS/LABEL_OPEN_PGP_NAME', 'openpgp'); } + Plugins.runSettingsViewModelHooks(false); + if (fCallback) { fCallback(); diff --git a/dev/bootstrap.js b/dev/bootstrap.js index 491cfeea1..8bc540e19 100644 --- a/dev/bootstrap.js +++ b/dev/bootstrap.js @@ -39,12 +39,16 @@ // export window['rl'] = window['rl'] || {}; window['rl']['i18n'] = _.bind(Translator.i18n, Translator); + window['rl']['addHook'] = _.bind(Plugins.addHook, Plugins); window['rl']['settingsGet'] = _.bind(Plugins.mainSettingsGet, Plugins); - window['rl']['remoteRequest'] = _.bind(Plugins.remoteRequest, Plugins); - window['rl']['pluginSettingsGet'] = _.bind(Plugins.settingsGet, Plugins); window['rl']['createCommand'] = Utils.createCommand; + window['rl']['addSettingsViewModel'] = _.bind(Plugins.addSettingsViewModel, Plugins); + + window['rl']['pluginRemoteRequest'] = _.bind(Plugins.remoteRequest, Plugins); + window['rl']['pluginSettingsGet'] = _.bind(Plugins.settingsGet, Plugins); + window['rl']['EmailModel'] = EmailModel; window['rl']['Enums'] = Enums; diff --git a/plugins/custom-settings-tab/LICENSE b/plugins/custom-settings-tab/LICENSE new file mode 100644 index 000000000..4aed64b3a --- /dev/null +++ b/plugins/custom-settings-tab/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015 RainLoop Team + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/custom-settings-tab/VERSION b/plugins/custom-settings-tab/VERSION new file mode 100644 index 000000000..9f8e9b69a --- /dev/null +++ b/plugins/custom-settings-tab/VERSION @@ -0,0 +1 @@ +1.0 \ No newline at end of file diff --git a/plugins/custom-settings-tab/index.php b/plugins/custom-settings-tab/index.php new file mode 100644 index 000000000..686eb649a --- /dev/null +++ b/plugins/custom-settings-tab/index.php @@ -0,0 +1,57 @@ +UseLangs(true); // start use langs folder + + $this->addJs('js/CustomUserSettings.js'); // add js file + + $this->addAjaxHook('AjaxGetCustomUserData', 'AjaxGetCustomUserData'); + $this->addAjaxHook('AjaxSaveCustomUserData', 'AjaxSaveCustomUserData'); + + $this->addTemplate('templates/PluginCustomSettingsTag.html'); + } + + /** + * @return array + */ + public function AjaxGetCustomUserData() + { + $aSettings = $this->getUserSettings(); + + $sUserFacebook = isset($aSettings['UserFacebook']) ? $aSettings['UserFacebook'] : ''; + $sUserSkype = isset($aSettings['UserSkype']) ? $aSettings['UserSkype'] : ''; + + // or get user's data from your custom storage ( DB / LDAP / ... ). + + \sleep(1); + return $this->ajaxResponse(__FUNCTION__, array( + 'UserFacebook' => $sUserFacebook, + 'UserSkype' => $sUserSkype + )); + } + + /** + * @return array + */ + public function AjaxSaveCustomUserData() + { + $sUserFacebook = $this->ajaxParam('UserFacebook'); + $sUserSkype = $this->ajaxParam('UserSkype'); + + // or put user's data to your custom storage ( DB / LDAP / ... ). + + \sleep(1); + return $this->ajaxResponse(__FUNCTION__, $this->saveUserSettings(array( + 'UserFacebook' => $sUserFacebook, + 'UserSkype' => $sUserSkype + ))); + } + +} + diff --git a/plugins/custom-settings-tab/js/CustomUserSettings.js b/plugins/custom-settings-tab/js/CustomUserSettings.js new file mode 100644 index 000000000..cd71c0877 --- /dev/null +++ b/plugins/custom-settings-tab/js/CustomUserSettings.js @@ -0,0 +1,73 @@ + +(function () { + + /** + * @constructor + */ + function CustomUserSettings() + { + this.userSkype = ko.observable(''); + this.userFacebook = ko.observable(''); + + this.loading = ko.observable(false); + this.saving = ko.observable(false); + + this.savingOrLoading = ko.computed(function () { + return this.loading() || this.saving(); + }, this); + } + + CustomUserSettings.prototype.customAjaxSaveData = function () + { + var self = this; + + if (this.saving()) + { + return false; + } + + this.saving(true); + + window.rl.pluginRemoteRequest(function (sResult, oData) { + + self.saving(false); + + if (window.rl.Enums.StorageResultType.Success === sResult && oData && oData.Result) + { + // true + } + else + { + // false + } + + }, 'AjaxSaveCustomUserData', { + 'UserSkype': this.userSkype(), + 'UserFacebook': this.userFacebook() + }); + }; + + CustomUserSettings.prototype.onBuild = function () // special function + { + var self = this; + + this.loading(true); + + window.rl.pluginRemoteRequest(function (sResult, oData) { + + self.loading(false); + + if (window.rl.Enums.StorageResultType.Success === sResult && oData && oData.Result) + { + self.userSkype(oData.Result.UserSkype || ''); + self.userFacebook(oData.Result.UserFacebook || ''); + } + + }, 'AjaxGetCustomUserData'); + + }; + + window.rl.addSettingsViewModel(CustomUserSettings, 'PluginCustomSettingsTag', + 'SETTINGS_CUSTOM_PLUGIN/TAB_NAME', 'custom'); + +}()); \ No newline at end of file diff --git a/plugins/custom-settings-tab/langs/en.ini b/plugins/custom-settings-tab/langs/en.ini new file mode 100644 index 000000000..1f3e63378 --- /dev/null +++ b/plugins/custom-settings-tab/langs/en.ini @@ -0,0 +1,6 @@ +[SETTINGS_CUSTOM_PLUGIN] +TAB_NAME = "Custom Plugin" +LEGEND_CUSTOM = "Custom Plugin (Example)" +LABEL_SKYPE = "Skype" +LABEL_FACEBOOK = "Facebook" +BUTTON_SAVE = "Save" \ No newline at end of file diff --git a/plugins/custom-settings-tab/langs/ru.ini b/plugins/custom-settings-tab/langs/ru.ini new file mode 100644 index 000000000..6b275600c --- /dev/null +++ b/plugins/custom-settings-tab/langs/ru.ini @@ -0,0 +1,6 @@ +[SETTINGS_CUSTOM_PLUGIN] +TAB_NAME = "Плагин" +LEGEND_CUSTOM = "Плагин (Пример)" +LABEL_SKYPE = "Skype" +LABEL_FACEBOOK = "Facebook" +BUTTON_SAVE = "Сохранить" \ No newline at end of file diff --git a/plugins/custom-settings-tab/templates/PluginCustomSettingsTag.html b/plugins/custom-settings-tab/templates/PluginCustomSettingsTag.html new file mode 100644 index 000000000..c0f3f4f90 --- /dev/null +++ b/plugins/custom-settings-tab/templates/PluginCustomSettingsTag.html @@ -0,0 +1,34 @@ +