From 83736ee3ed6532f261feb7605fc3bdfc4a0e7235 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 2 Nov 2012 23:09:32 +0100 Subject: [PATCH] Added style chooser and added .doubleColumned Every .containerList can now be toggled into a two-column list by simply adding .doubleColumned without any further markup changes required. Replaces .userList and .simpleUserList --- com.woltlab.wcf/template/headInclude.tpl | 4 +- com.woltlab.wcf/template/styleChooser.tpl | 19 ++++ wcfsetup/install/files/js/WCF.js | 92 +++++++++++++++++++ .../lib/data/style/StyleAction.class.php | 69 ++++++++++++++ .../install/files/lib/system/WCF.class.php | 13 +++ .../system/session/SessionHandler.class.php | 36 +++++++- wcfsetup/install/files/style/global.less | 4 + wcfsetup/install/files/style/layout.less | 63 +++++++++++++ wcfsetup/install/lang/de.xml | 4 + 9 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 com.woltlab.wcf/template/styleChooser.tpl diff --git a/com.woltlab.wcf/template/headInclude.tpl b/com.woltlab.wcf/template/headInclude.tpl index 7a88cdbe0d..54b9d2cea7 100644 --- a/com.woltlab.wcf/template/headInclude.tpl +++ b/com.woltlab.wcf/template/headInclude.tpl @@ -66,7 +66,8 @@ 'wcf.global.confirmation.cancel': '{lang}wcf.global.confirmation.cancel{/lang}', 'wcf.global.confirmation.confirm': '{lang}wcf.global.confirmation.confirm{/lang}', 'wcf.global.confirmation.title': '{lang}wcf.global.confirmation.title{/lang}', - 'wcf.sitemap.title': '{lang}wcf.sitemap.title{/lang}' + 'wcf.sitemap.title': '{lang}wcf.sitemap.title{/lang}', + 'wcf.style.changeStyle': '{lang}wcf.style.changeStyle{/lang}' {event name='javascriptLanguageImport'} }); @@ -94,6 +95,7 @@ new WCF.Effect.SmoothScroll(); new WCF.Effect.BalloonTooltip(); new WCF.Sitemap(); + new WCF.Style.Chooser(); WCF.Dropdown.init(); {event name='javascriptInit'} diff --git a/com.woltlab.wcf/template/styleChooser.tpl b/com.woltlab.wcf/template/styleChooser.tpl new file mode 100644 index 0000000000..7cc02c2d5c --- /dev/null +++ b/com.woltlab.wcf/template/styleChooser.tpl @@ -0,0 +1,19 @@ +
+
    + {foreach from=$styleList item=style} +
  1. +
    + + + +
    +
    +

    {$style->styleName}

    +
    + {if $style->styleDescription}{$style->styleDescription}{/if} +
    +
    +
  2. + {/foreach} +
+
\ No newline at end of file diff --git a/wcfsetup/install/files/js/WCF.js b/wcfsetup/install/files/js/WCF.js index 6595819ec4..3700a0decb 100755 --- a/wcfsetup/install/files/js/WCF.js +++ b/wcfsetup/install/files/js/WCF.js @@ -6724,6 +6724,98 @@ WCF.Language.Chooser = Class.extend({ } }); +/** + * Namespace for style related classes. + */ +WCF.Style = { }; + +/** + * Provides a visual style chooser. + */ +WCF.Style.Chooser = Class.extend({ + /** + * dialog overlay + * @var jQuery + */ + _dialog: null, + + /** + * action proxy + * @var WCF.Action.Proxy + */ + _proxy: null, + + /** + * Initializes the style chooser class. + */ + init: function() { + $('
  • ' + WCF.Language.get('wcf.style.changeStyle') + '
  • ').appendTo($('#footerNavigation > ul')).click($.proxy(this._showDialog, this)); + + this._proxy = new WCF.Action.Proxy({ + success: $.proxy(this._success, this) + }); + }, + + /** + * Displays the style chooser dialog. + */ + _showDialog: function() { + if (this._dialog === null) { + this._dialog = $('
    ').hide().appendTo(document.body); + this._loadDialog(); + } + else { + this._dialog.wcfDialog({ + title: WCF.Language.get('wcf.style.changeStyle') + }); + } + }, + + /** + * Loads the style chooser dialog. + */ + _loadDialog: function() { + this._proxy.setOption('data', { + actionName: 'getStyleChooser', + className: 'wcf\\data\\style\\StyleAction' + }); + this._proxy.sendRequest(); + }, + + /** + * Handles successful AJAX requests. + * + * @param object data + * @param string textStatus + * @param jQuery jqXHR + */ + _success: function(data, textStatus, jqXHR) { + if (data.returnValues.actionName === 'changeStyle') { + window.location.reload(); + return; + } + + this._dialog.html(data.returnValues.template); + this._dialog.find('li').addClass('pointer').click($.proxy(this._click, this)); + + this._showDialog(); + }, + + /** + * Changes user style. + * + * @param object event + */ + _click: function(event) { + this._proxy.setOption('data', { + actionName: 'changeStyle', + className: 'wcf\\data\\style\\StyleAction', + objectIDs: [ $(event.currentTarget).data('styleID') ] + }); + this._proxy.sendRequest(); + } +}); + /** * WCF implementation for nested sortables. */ diff --git a/wcfsetup/install/files/lib/data/style/StyleAction.class.php b/wcfsetup/install/files/lib/data/style/StyleAction.class.php index 0a09ed2958..c93ce22ce1 100644 --- a/wcfsetup/install/files/lib/data/style/StyleAction.class.php +++ b/wcfsetup/install/files/lib/data/style/StyleAction.class.php @@ -25,6 +25,11 @@ use wcf\util\StringUtil; * @category Community Framework */ class StyleAction extends AbstractDatabaseObjectAction { + /** + * @see wcf\data\AbstractDatabaseObjectAction::$allowGuestAccess + */ + protected $allowGuestAccess = array('changeStyle', 'getStyleChooser'); + /** * @see wcf\data\AbstractDatabaseObjectAction::$className */ @@ -40,6 +45,12 @@ class StyleAction extends AbstractDatabaseObjectAction { */ protected $permissionsUpdate = array('admin.style.canEditStyle'); + /** + * style object + * @var wcf\data\style\Style + */ + public $style = null; + /** * style editor object * @var wcf\data\style\StyleEditor @@ -447,4 +458,62 @@ class StyleAction extends AbstractDatabaseObjectAction { $style->update(array('disabled' => $disabled)); } } + + /** + * Validates parameters to change user style. + * + * @todo take care of wcf1_style_to_package as it might apply further restrictions + */ + public function validateChangeStyle() { + $this->style = $this->getSingleObject(); + if ($this->style->disabled && !WCF::getSession()->getPermission('admin.style.canUseDisabledStyle')) { + throw new PermissionDeniedException(); + } + } + + /** + * Changes user style. + * + * @return array + */ + public function changeStyle() { + StyleHandler::getInstance()->changeStyle($this->style->styleID); + if (StyleHandler::getInstance()->getStyle()->styleID == $this->style->styleID) { + WCF::getSession()->setStyleID($this->style->styleID); + } + + return array( + 'actionName' => 'changeStyle' + ); + } + + /** + * Does nothing. + */ + public function validateGetStyleChooser() { } + + /** + * Returns the style chooser dialog. + * + * @todo take care of wcf1_style_to_package as it might apply further restrictions + * + * @return array + */ + public function getStyleChooser() { + $styleList = new StyleList(); + if (!WCF::getSession()->getPermission('admin.style.canUseDisabledStyle')) { + $styleList->getConditionBuilder()->add("style.disabled = ?", array(0)); + } + $styleList->sqlOrderBy = "style.styleName ASC"; + $styleList->readObjects(); + + WCF::getTPL()->assign(array( + 'styleList' => $styleList + )); + + return array( + 'actionName' => 'getStyleChooser', + 'template' => WCF::getTPL()->fetch('styleChooser') + ); + } } diff --git a/wcfsetup/install/files/lib/system/WCF.class.php b/wcfsetup/install/files/lib/system/WCF.class.php index 66fa36581f..4f7b447a2a 100644 --- a/wcfsetup/install/files/lib/system/WCF.class.php +++ b/wcfsetup/install/files/lib/system/WCF.class.php @@ -361,6 +361,19 @@ class WCF { self::$tplObj = TemplateEngine::getInstance(); self::getTPL()->setLanguageID(self::getLanguage()->languageID); $this->assignDefaultTemplateVariables(); + + $this->initStyle(); + } + + /** + * Initializes the user's style. + */ + protected function initStyle() { + if (isset($_REQUEST['styleID'])) { + WCF::getSession()->setStyleID(intval($_REQUEST['styleID'])); + } + + StyleHandler::getInstance()->changeStyle(WCF::getSession()->getStyleID()); } /** diff --git a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php index 43441324e8..486386d1fb 100644 --- a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php +++ b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php @@ -70,6 +70,12 @@ class SessionHandler extends SingletonFactory { */ protected $sessionEditorClassName = ''; + /** + * style id + * @var integer + */ + protected $styleID = null; + /** * enable cookie support * @var boolean @@ -138,8 +144,9 @@ class SessionHandler extends SingletonFactory { $this->initSecurityToken(); $this->defineConstants(); - // assign language id - $this->languageID = $this->user->languageID; + // assign language and style id + $this->languageID = ($this->getVar('languageID') === null) ? $this->user->languageID : $this->getVar('languageID'); + $this->styleID = ($this->getVar('styleID') === null) ? $this->user->styleID : $this->getVar('styleID'); // init environment variables $this->initEnvironment(); @@ -472,6 +479,10 @@ class SessionHandler extends SingletonFactory { AND userID = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->sessionID, $this->userID)); + + // reset session variables + $this->variables = array(); + $this->variablesChanged = true; } // update user reference @@ -489,6 +500,7 @@ class SessionHandler extends SingletonFactory { $this->groupData = null; $this->languageIDs = null; $this->languageID = $this->user->languageID; + $this->styleID = $this->user->styleID; // truncate session variables } @@ -557,6 +569,26 @@ class SessionHandler extends SingletonFactory { */ public function setLanguageID($languageID) { $this->languageID = $languageID; + $this->register('languageID', $this->languageID); + } + + /** + * Returns currently active style id. + * + * @return integer + */ + public function getStyleID() { + return $this->styleID; + } + + /** + * Sets the currently active style id. + * + * @param integer $styleID + */ + public function setStyleID($styleID) { + $this->styleID = $styleID; + $this->register('styleID', $this->styleID); } /** diff --git a/wcfsetup/install/files/style/global.less b/wcfsetup/install/files/style/global.less index e9f92f859b..d5d3c1139c 100644 --- a/wcfsetup/install/files/style/global.less +++ b/wcfsetup/install/files/style/global.less @@ -57,6 +57,10 @@ a { margin-top: @wcfGapMedium; } +.pointer { + cursor: pointer; +} + /* icons */ .icon(@imageSize) { .square(@imageSize); diff --git a/wcfsetup/install/files/style/layout.less b/wcfsetup/install/files/style/layout.less index 26e93959c7..4a39799e2d 100644 --- a/wcfsetup/install/files/style/layout.less +++ b/wcfsetup/install/files/style/layout.less @@ -432,6 +432,69 @@ > * > li { padding: @wcfGapMedium @wcfGapLarge; } + + &.doubleColumned { + overflow: hidden; + + > li { + padding: 0; + float: left; + width: 50%; + height: 90px; + overflow: hidden; + + &:nth-child(even) { + float: right; + } + + &:nth-child(4n), &:nth-child(4n+1) { + background-color: @wcfContainerBackgroundColor; + } + + &:nth-child(4n+2), &:nth-child(4n+3) { + background-color: @wcfContainerAccentBackgroundColor; + } + + &:hover { + background-color: @wcfContainerHoverBackgroundColor; + + > div > .buttonList { + opacity: 1; + } + } + + > div { + padding: 14px 21px; + position: relative; + + > .buttonList { + opacity: 0; + position: absolute; + right: 0; + top: 0; + + .transition(opacity, .1s); + } + } + } + + &:after { + content: ""; + display: table; + clear: left; + } + } + + &.styleList > li > div.box64 { + > span { + text-align: center; + width: 110px; + } + + > div { + margin-left: 115px; + } + } } /* boxes with an image */ diff --git a/wcfsetup/install/lang/de.xml b/wcfsetup/install/lang/de.xml index da108bd2eb..3545af19e2 100644 --- a/wcfsetup/install/lang/de.xml +++ b/wcfsetup/install/lang/de.xml @@ -700,6 +700,10 @@ + + + + -- 2.20.1