Merge branch 'userdesign' into 0.8.x
* userdesign: (56 commits) Fix for background image repetition for various page heights Removed height:100% for better background image repetition A little more specific selector for notice reply Have user favorites page show user's design Placed a check to make sure there is a reply button in a notice before Make MailboxAction read only Remove stale reference to deprecated personal.php Uppercase hex color values Default to image being on, no tile after upload Fix sidebar color bug default design Update background image settings to use bitflags It was accidently removed Dynamically tile background image and turn background image on or off Show a background img in settings form IE7/8 CSS update for user design Enable tiling of background imgs for Designs Added background image tile flag to Design Init styles for tile and image use on/off for user design settings Added form option to tile background image and to turn it on and off Add background dir ...
This commit is contained in:
commit
6c7bdf9df6
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
avatar/*
|
||||
background/*
|
||||
files/*
|
||||
file/*
|
||||
_darcs/*
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* @category Settings
|
||||
* @package Laconica
|
||||
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||
* @author Zach Copley <zach@controlyourself.ca>
|
||||
* @copyright 2008-2009 Control Yourself, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
|
@ -31,9 +32,8 @@ if (!defined('LACONICA')) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/accountsettingsaction.php';
|
||||
|
||||
|
||||
require_once INSTALLDIR . '/lib/accountsettingsaction.php';
|
||||
require_once INSTALLDIR . '/lib/webcolor.php';
|
||||
|
||||
class DesignsettingsAction extends AccountSettingsAction
|
||||
{
|
||||
|
@ -56,7 +56,8 @@ class DesignsettingsAction extends AccountSettingsAction
|
|||
|
||||
function getInstructions()
|
||||
{
|
||||
return _('Customize the way your profile looks with a background image and a colour palette of your choice.');
|
||||
return _('Customize the way your profile looks ' .
|
||||
'with a background image and a colour palette of your choice.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,29 +71,87 @@ class DesignsettingsAction extends AccountSettingsAction
|
|||
function showContent()
|
||||
{
|
||||
$user = common_current_user();
|
||||
$design = $user->getDesign();
|
||||
|
||||
if (empty($design)) {
|
||||
$design = $this->defaultDesign();
|
||||
}
|
||||
|
||||
$this->elementStart('form', array('method' => 'post',
|
||||
'enctype' => 'multipart/form-data',
|
||||
'id' => 'form_settings_design',
|
||||
'class' => 'form_settings',
|
||||
'action' =>
|
||||
common_local_url('designsettings')));
|
||||
common_local_url('designsettings')));
|
||||
$this->elementStart('fieldset');
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
$this->elementStart('fieldset', array('id' => 'settings_design_background-image'));
|
||||
$this->elementStart('fieldset', array('id' =>
|
||||
'settings_design_background-image'));
|
||||
$this->element('legend', null, _('Change background image'));
|
||||
$this->elementStart('ul', 'form_data');
|
||||
$this->elementStart('li');
|
||||
$this->element('label', array('for' => 'design_background-image_file'),
|
||||
$this->element('label', array('for' => 'design_background-image_file'),
|
||||
_('Upload file'));
|
||||
$this->element('input', array('name' => 'design_background-image_file',
|
||||
'type' => 'file',
|
||||
'id' => 'design_background-image_file'));
|
||||
$this->element('p', 'form_guide', _('You can upload your personal background image. The maximum file size is 2Mb.'));
|
||||
$this->element('p', 'form_guide', _('You can upload your personal ' .
|
||||
'background image. The maximum file size is 2Mb.'));
|
||||
$this->element('input', array('name' => 'MAX_FILE_SIZE',
|
||||
'type' => 'hidden',
|
||||
'id' => 'MAX_FILE_SIZE',
|
||||
'value' => ImageFile::maxFileSizeInt()));
|
||||
$this->elementEnd('li');
|
||||
|
||||
if (!empty($design->backgroundimage)) {
|
||||
|
||||
$this->elementStart('li', array('id' => 'design_background-image_onoff'));
|
||||
|
||||
$this->element('img', array('src' =>
|
||||
Design::url($design->backgroundimage)));
|
||||
|
||||
$attrs = array('name' => 'design_background-image_onoff',
|
||||
'type' => 'radio',
|
||||
'id' => 'design_background-image_on',
|
||||
'class' => 'radio',
|
||||
'value' => 'on');
|
||||
|
||||
if ($design->disposition & BACKGROUND_ON) {
|
||||
$attrs['checked'] = 'checked';
|
||||
}
|
||||
|
||||
$this->element('input', $attrs);
|
||||
|
||||
$this->element('label', array('for' => 'design_background-image_on',
|
||||
'class' => 'radio'),
|
||||
_('On'));
|
||||
|
||||
$attrs = array('name' => 'design_background-image_onoff',
|
||||
'type' => 'radio',
|
||||
'id' => 'design_background-image_off',
|
||||
'class' => 'radio',
|
||||
'value' => 'off');
|
||||
|
||||
if ($design->disposition & BACKGROUND_OFF) {
|
||||
$attrs['checked'] = 'checked';
|
||||
}
|
||||
|
||||
$this->element('input', $attrs);
|
||||
|
||||
$this->element('label', array('for' => 'design_background-image_off',
|
||||
'class' => 'radio'),
|
||||
_('Off'));
|
||||
$this->element('p', 'form_guide', _('Turn background image on or off.'));
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
|
||||
$this->elementStart('li');
|
||||
$this->checkbox('design_background-image_repeat',
|
||||
_('Tile background image'),
|
||||
($design->disposition & BACKGROUND_TILE) ? true : false );
|
||||
$this->elementEnd('li');
|
||||
|
||||
$this->elementEnd('ul');
|
||||
$this->elementEnd('fieldset');
|
||||
|
||||
|
@ -100,61 +159,93 @@ class DesignsettingsAction extends AccountSettingsAction
|
|||
$this->element('legend', null, _('Change colours'));
|
||||
$this->elementStart('ul', 'form_data');
|
||||
|
||||
//This is a JSON object in the DB field. Here for testing. Remove later.
|
||||
$userSwatch = '{"body":{"background-color":"#F0F2F5"},
|
||||
"#content":{"background-color":"#FFFFFF"},
|
||||
"#aside_primary":{"background-color":"#CEE1E9"},
|
||||
"html body":{"color":"#000000"},
|
||||
"a":{"color":"#002E6E"}}';
|
||||
try {
|
||||
|
||||
//Default theme swatch -- Where should this be stored?
|
||||
$defaultSwatch = array('body' => array('background-color' => '#F0F2F5'),
|
||||
'#content' => array('background-color' => '#FFFFFF'),
|
||||
'#aside_primary' => array('background-color' => '#CEE1E9'),
|
||||
'html body' => array('color' => '#000000'),
|
||||
'a' => array('color' => '#002E6E'));
|
||||
$bgcolor = new WebColor($design->backgroundcolor);
|
||||
|
||||
$userSwatch = ($userSwatch) ? json_decode($userSwatch, true) : $defaultSwatch;
|
||||
|
||||
$s = 0;
|
||||
$labelSwatch = array('Background',
|
||||
'Content',
|
||||
'Sidebar',
|
||||
'Text',
|
||||
'Links');
|
||||
foreach($userSwatch as $propertyvalue => $value) {
|
||||
$foo = array_values($value);
|
||||
$this->elementStart('li');
|
||||
$this->element('label', array('for' => 'swatch-'.$s), _($labelSwatch[$s]));
|
||||
$this->element('input', array('name' => 'swatch-'.$s, //prefer swatch[$s] ?
|
||||
$this->element('label', array('for' => 'swatch-1'), _('Background'));
|
||||
$this->element('input', array('name' => 'design_background',
|
||||
'type' => 'text',
|
||||
'id' => 'swatch-'.$s,
|
||||
'id' => 'swatch-1',
|
||||
'class' => 'swatch',
|
||||
'maxlength' => '7',
|
||||
'size' => '7',
|
||||
'value' => $foo[0]));
|
||||
'value' => '#' . $bgcolor->hexValue()));
|
||||
$this->elementEnd('li');
|
||||
$s++;
|
||||
}
|
||||
|
||||
$this->elementEnd('ul');
|
||||
$this->elementEnd('fieldset');
|
||||
$ccolor = new WebColor($design->contentcolor);
|
||||
|
||||
$this->element('input', array('id' => 'settings_design_reset',
|
||||
'type' => 'reset',
|
||||
'value' => 'Reset',
|
||||
'class' => 'submit form_action-primary',
|
||||
'title' => _('Reset back to default')));
|
||||
$this->submit('save', _('Save'), 'submit form_action-secondary', 'save', _('Save design'));
|
||||
$this->elementStart('li');
|
||||
$this->element('label', array('for' => 'swatch-2'), _('Content'));
|
||||
$this->element('input', array('name' => 'design_content',
|
||||
'type' => 'text',
|
||||
'id' => 'swatch-2',
|
||||
'class' => 'swatch',
|
||||
'maxlength' => '7',
|
||||
'size' => '7',
|
||||
'value' => '#' . $ccolor->hexValue()));
|
||||
$this->elementEnd('li');
|
||||
|
||||
$sbcolor = new WebColor($design->sidebarcolor);
|
||||
|
||||
$this->elementStart('li');
|
||||
$this->element('label', array('for' => 'swatch-3'), _('Sidebar'));
|
||||
$this->element('input', array('name' => 'design_sidebar',
|
||||
'type' => 'text',
|
||||
'id' => 'swatch-3',
|
||||
'class' => 'swatch',
|
||||
'maxlength' => '7',
|
||||
'size' => '7',
|
||||
'value' => '#' . $sbcolor->hexValue()));
|
||||
$this->elementEnd('li');
|
||||
|
||||
$tcolor = new WebColor($design->textcolor);
|
||||
|
||||
$this->elementStart('li');
|
||||
$this->element('label', array('for' => 'swatch-4'), _('Text'));
|
||||
$this->element('input', array('name' => 'design_text',
|
||||
'type' => 'text',
|
||||
'id' => 'swatch-4',
|
||||
'class' => 'swatch',
|
||||
'maxlength' => '7',
|
||||
'size' => '7',
|
||||
'value' => '#' . $tcolor->hexValue()));
|
||||
$this->elementEnd('li');
|
||||
|
||||
$lcolor = new WebColor($design->linkcolor);
|
||||
|
||||
$this->elementStart('li');
|
||||
$this->element('label', array('for' => 'swatch-5'), _('Links'));
|
||||
$this->element('input', array('name' => 'design_links',
|
||||
'type' => 'text',
|
||||
'id' => 'swatch-5',
|
||||
'class' => 'swatch',
|
||||
'maxlength' => '7',
|
||||
'size' => '7',
|
||||
'value' => '#' . $lcolor->hexValue()));
|
||||
|
||||
$this->elementEnd('li');
|
||||
|
||||
} catch (WebColorException $e) {
|
||||
common_log(LOG_ERR, 'Bad color values in design ID: ' .
|
||||
$design->id);
|
||||
}
|
||||
|
||||
$this->elementEnd('ul');
|
||||
$this->elementEnd('fieldset');
|
||||
|
||||
$this->element('input', array('id' => 'settings_design_reset',
|
||||
'type' => 'reset',
|
||||
'value' => 'Reset',
|
||||
'class' => 'submit form_action-primary',
|
||||
'title' => _('Reset back to default')));
|
||||
|
||||
$this->submit('save', _('Save'), 'submit form_action-secondary',
|
||||
'save', _('Save design'));
|
||||
|
||||
/*TODO: Check submitted form values:
|
||||
json_encode(form values)
|
||||
if submitted Swatch == DefaultSwatch, don't store in DB.
|
||||
else store in BD
|
||||
*/
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,63 +259,37 @@ else store in BD
|
|||
|
||||
function handlePost()
|
||||
{
|
||||
/*
|
||||
// CSRF protection
|
||||
// XXX: Robin's workaround for a bug in PHP where $_POST
|
||||
// and $_FILE are empty in the case that the uploaded
|
||||
// file is bigger than PHP is configured to handle.
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
}
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if (empty($_POST) && $_SERVER['CONTENT_LENGTH']) {
|
||||
|
||||
$user = common_current_user();
|
||||
assert(!is_null($user)); // should already be checked
|
||||
$msg = _('The server was unable to handle that much POST ' .
|
||||
'data (%s bytes) due to its current configuration.');
|
||||
|
||||
// FIXME: scrub input
|
||||
|
||||
$newpassword = $this->arg('newpassword');
|
||||
$confirm = $this->arg('confirm');
|
||||
|
||||
# Some validation
|
||||
|
||||
if (strlen($newpassword) < 6) {
|
||||
$this->showForm(_('Password must be 6 or more characters.'));
|
||||
return;
|
||||
} else if (0 != strcmp($newpassword, $confirm)) {
|
||||
$this->showForm(_('Passwords don\'t match.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if ($user->password) {
|
||||
$oldpassword = $this->arg('oldpassword');
|
||||
|
||||
if (!common_check_user($user->nickname, $oldpassword)) {
|
||||
$this->showForm(_('Incorrect old password'));
|
||||
return;
|
||||
$this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
||||
}
|
||||
}
|
||||
|
||||
$original = clone($user);
|
||||
|
||||
$user->password = common_munge_password($newpassword, $user->id);
|
||||
|
||||
$val = $user->validate();
|
||||
if ($val !== true) {
|
||||
$this->showForm(_('Error saving user; invalid.'));
|
||||
// CSRF protection
|
||||
$token = $this->trimmed('token');
|
||||
if (!$token || $token != common_session_token()) {
|
||||
$this->showForm(_('There was a problem with your session token. '.
|
||||
'Try again, please.'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$user->update($original)) {
|
||||
$this->serverError(_('Can\'t save new password.'));
|
||||
return;
|
||||
if ($this->arg('save')) {
|
||||
$this->saveDesign();
|
||||
} else if ($this->arg('reset')) {
|
||||
$this->resetDesign();
|
||||
} else {
|
||||
$this->showForm(_('Unexpected form submission.'));
|
||||
}
|
||||
|
||||
$this->showForm(_('Password saved.'), true);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the Farbtastic stylesheet
|
||||
*
|
||||
|
@ -254,11 +319,199 @@ else store in BD
|
|||
parent::showScripts();
|
||||
|
||||
$farbtasticPack = common_path('js/farbtastic/farbtastic.js');
|
||||
$farbtasticGo = common_path('js/farbtastic/farbtastic.go.js');
|
||||
$userDesignGo = common_path('js/userdesign.go.js');
|
||||
|
||||
$this->element('script', array('type' => 'text/javascript',
|
||||
'src' => $farbtasticPack));
|
||||
$this->element('script', array('type' => 'text/javascript',
|
||||
'src' => $farbtasticGo));
|
||||
'src' => $userDesignGo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a default user design
|
||||
*
|
||||
* @return Design design
|
||||
*/
|
||||
|
||||
function defaultDesign()
|
||||
{
|
||||
$defaults = common_config('site', 'design');
|
||||
|
||||
$design = new Design();
|
||||
|
||||
try {
|
||||
|
||||
$color = new WebColor();
|
||||
|
||||
$color->parseColor($defaults['backgroundcolor']);
|
||||
$design->backgroundcolor = $color->intValue();
|
||||
|
||||
$color->parseColor($defaults['contentcolor']);
|
||||
$design->contentcolor = $color->intValue();
|
||||
|
||||
$color->parseColor($defaults['sidebarcolor']);
|
||||
$design->sidebarcolor = $color->intValue();
|
||||
|
||||
$color->parseColor($defaults['textcolor']);
|
||||
$design->textcolor = $color->intValue();
|
||||
|
||||
$color->parseColor($defaults['linkcolor']);
|
||||
$design->linkcolor = $color->intValue();
|
||||
|
||||
$design->backgroundimage = $defaults['backgroundimage'];
|
||||
|
||||
$design->disposition = $defaults['disposition'];
|
||||
|
||||
} catch (WebColorException $e) {
|
||||
common_log(LOG_ERR, _('Bad default color settings: ' .
|
||||
$e->getMessage()));
|
||||
}
|
||||
|
||||
return $design;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save or update the user's design settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function saveDesign()
|
||||
{
|
||||
try {
|
||||
|
||||
$bgcolor = new WebColor($this->trimmed('design_background'));
|
||||
$ccolor = new WebColor($this->trimmed('design_content'));
|
||||
$sbcolor = new WebColor($this->trimmed('design_sidebar'));
|
||||
$tcolor = new WebColor($this->trimmed('design_text'));
|
||||
$lcolor = new WebColor($this->trimmed('design_links'));
|
||||
|
||||
} catch (WebColorException $e) {
|
||||
$this->showForm($e->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
$onoff = $this->arg('design_background-image_onoff');
|
||||
|
||||
$on = false;
|
||||
$off = false;
|
||||
$tile = false;
|
||||
|
||||
if ($onoff == 'on') {
|
||||
$on = true;
|
||||
} else {
|
||||
$off = true;
|
||||
}
|
||||
|
||||
$repeat = $this->boolean('design_background-image_repeat');
|
||||
|
||||
if ($repeat) {
|
||||
$tile = true;
|
||||
}
|
||||
|
||||
$user = common_current_user();
|
||||
$design = $user->getDesign();
|
||||
|
||||
if (!empty($design)) {
|
||||
|
||||
$original = clone($design);
|
||||
|
||||
$design->backgroundcolor = $bgcolor->intValue();
|
||||
$design->contentcolor = $ccolor->intValue();
|
||||
$design->sidebarcolor = $sbcolor->intValue();
|
||||
$design->textcolor = $tcolor->intValue();
|
||||
$design->linkcolor = $lcolor->intValue();
|
||||
$design->backgroundimage = $filepath;
|
||||
|
||||
$design->setDisposition($on, $off, $tile);
|
||||
|
||||
$result = $design->update($original);
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||
$this->showForm(_('Couldn\'t update your design.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// update design
|
||||
} else {
|
||||
|
||||
$user->query('BEGIN');
|
||||
|
||||
// save new design
|
||||
$design = new Design();
|
||||
|
||||
$design->backgroundcolor = $bgcolor->intValue();
|
||||
$design->contentcolor = $ccolor->intValue();
|
||||
$design->sidebarcolor = $sbcolor->intValue();
|
||||
$design->textcolor = $tcolor->intValue();
|
||||
$design->linkcolor = $lcolor->intValue();
|
||||
$design->backgroundimage = $filepath;
|
||||
|
||||
$design->setDisposition($on, $off, $tile);
|
||||
|
||||
$id = $design->insert();
|
||||
|
||||
if (empty($id)) {
|
||||
common_log_db_error($id, 'INSERT', __FILE__);
|
||||
$this->showForm(_('Unable to save your design settings!'));
|
||||
return;
|
||||
}
|
||||
|
||||
$original = clone($user);
|
||||
$user->design_id = $id;
|
||||
$result = $user->update($original);
|
||||
|
||||
if (empty($result)) {
|
||||
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||
$this->showForm(_('Unable to save your design settings!'));
|
||||
$user->query('ROLLBACK');
|
||||
return;
|
||||
}
|
||||
|
||||
$user->query('COMMIT');
|
||||
|
||||
}
|
||||
|
||||
// Now that we have a Design ID we can add a file to the design.
|
||||
// XXX: This is an additional DB hit, but figured having the image
|
||||
// associated with the Design rather than the User was worth
|
||||
// it. -- Zach
|
||||
|
||||
if ($_FILES['design_background-image_file']['error'] ==
|
||||
UPLOAD_ERR_OK) {
|
||||
|
||||
$filepath = null;
|
||||
|
||||
try {
|
||||
$imagefile =
|
||||
ImageFile::fromUpload('design_background-image_file');
|
||||
} catch (Exception $e) {
|
||||
$this->showForm($e->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
$filename = Design::filename($design->id,
|
||||
image_type_to_extension($imagefile->type),
|
||||
common_timestamp());
|
||||
|
||||
$filepath = Design::path($filename);
|
||||
|
||||
move_uploaded_file($imagefile->filepath, $filepath);
|
||||
|
||||
$original = clone($design);
|
||||
$design->backgroundimage = $filename;
|
||||
$design->setDisposition(true, false, false);
|
||||
$result = $design->update($original);
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||
$this->showForm(_('Couldn\'t update your design.'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->showForm(_('Design preferences saved.'), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
if (!defined('LACONICA')) { exit(1); }
|
||||
|
||||
class InviteAction extends Action
|
||||
class InviteAction extends CurrentUserDesignAction
|
||||
{
|
||||
var $mode = null;
|
||||
var $error = null;
|
||||
|
|
|
@ -45,9 +45,8 @@ require_once INSTALLDIR.'/lib/feedlist.php';
|
|||
* @link http://laconi.ca/
|
||||
*/
|
||||
|
||||
class RepliesAction extends Action
|
||||
class RepliesAction extends OwnerDesignAction
|
||||
{
|
||||
var $user = null;
|
||||
var $page = null;
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php';
|
|||
* @link http://laconi.ca/
|
||||
*/
|
||||
|
||||
class ShowfavoritesAction extends Action
|
||||
class ShowfavoritesAction extends CurrentUserDesignAction
|
||||
{
|
||||
/** User we're getting the faves of */
|
||||
var $user = null;
|
||||
|
|
|
@ -46,9 +46,8 @@ require_once INSTALLDIR.'/lib/grouplist.php';
|
|||
* @link http://laconi.ca/
|
||||
*/
|
||||
|
||||
class UsergroupsAction extends Action
|
||||
class UsergroupsAction extends OwnerDesignAction
|
||||
{
|
||||
var $user = null;
|
||||
var $page = null;
|
||||
var $profile = null;
|
||||
|
||||
|
|
0
background/.gitignore
vendored
Normal file
0
background/.gitignore
vendored
Normal file
155
classes/Design.php
Normal file
155
classes/Design.php
Normal file
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
/*
|
||||
* Laconica - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2009, Control Yourself, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
define('BACKGROUND_ON', 1);
|
||||
define('BACKGROUND_OFF', 2);
|
||||
define('BACKGROUND_TILE', 4);
|
||||
|
||||
/**
|
||||
* Table Definition for design
|
||||
*/
|
||||
|
||||
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
|
||||
require_once INSTALLDIR . '/lib/webcolor.php';
|
||||
|
||||
class Design extends Memcached_DataObject
|
||||
{
|
||||
###START_AUTOCODE
|
||||
/* the code below is auto generated do not remove the above tag */
|
||||
|
||||
public $__table = 'design'; // table name
|
||||
public $id; // int(4) primary_key not_null
|
||||
public $backgroundcolor; // int(4)
|
||||
public $contentcolor; // int(4)
|
||||
public $sidebarcolor; // int(4)
|
||||
public $textcolor; // int(4)
|
||||
public $linkcolor; // int(4)
|
||||
public $backgroundimage; // varchar(255)
|
||||
public $disposition; // tinyint(1) default_1
|
||||
|
||||
/* Static get */
|
||||
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Design',$k,$v); }
|
||||
|
||||
/* the code above is auto generated do not remove the tag below */
|
||||
###END_AUTOCODE
|
||||
|
||||
function showCSS($out)
|
||||
{
|
||||
try {
|
||||
|
||||
$bgcolor = new WebColor($this->backgroundcolor);
|
||||
$ccolor = new WebColor($this->contentcolor);
|
||||
$sbcolor = new WebColor($this->sidebarcolor);
|
||||
$tcolor = new WebColor($this->textcolor);
|
||||
$lcolor = new WebColor($this->linkcolor);
|
||||
|
||||
} catch (WebColorException $e) {
|
||||
// This shouldn't happen
|
||||
common_log(LOG_ERR, "Unable to create color for design $id.",
|
||||
__FILE__);
|
||||
}
|
||||
|
||||
$css = 'body { background-color: #' . $bgcolor->hexValue() . ' }' . "\n";
|
||||
$css .= '#content, #site_nav_local_views .current a { background-color: #';
|
||||
$css .= $ccolor->hexValue() . '} '."\n";
|
||||
$css .= '#aside_primary { background-color: #'. $sbcolor->hexValue() . ' }' . "\n";
|
||||
$css .= 'html body { color: #'. $tcolor->hexValue() . ' }'. "\n";
|
||||
$css .= 'a { color: #' . $lcolor->hexValue() . ' }' . "\n";
|
||||
|
||||
if (!empty($this->backgroundimage) &&
|
||||
$this->disposition & BACKGROUND_ON) {
|
||||
|
||||
$repeat = ($this->disposition & BACKGROUND_TILE) ?
|
||||
'background-repeat:repeat;' :
|
||||
'background-repeat:no-repeat;';
|
||||
|
||||
$css .= 'body { background-image:url(' .
|
||||
Design::url($this->backgroundimage) .
|
||||
'); ' . $repeat . ' }' . "\n";
|
||||
}
|
||||
|
||||
$out->element('style', array('type' => 'text/css'), $css);
|
||||
|
||||
}
|
||||
|
||||
static function filename($id, $extension, $extra=null)
|
||||
{
|
||||
return $id . (($extra) ? ('-' . $extra) : '') . $extension;
|
||||
}
|
||||
|
||||
static function path($filename)
|
||||
{
|
||||
$dir = common_config('background', 'dir');
|
||||
|
||||
if ($dir[strlen($dir)-1] != '/') {
|
||||
$dir .= '/';
|
||||
}
|
||||
|
||||
return $dir . $filename;
|
||||
}
|
||||
|
||||
static function url($filename)
|
||||
{
|
||||
$path = common_config('background', 'path');
|
||||
|
||||
if ($path[strlen($path)-1] != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
|
||||
if ($path[0] != '/') {
|
||||
$path = '/'.$path;
|
||||
}
|
||||
|
||||
$server = common_config('background', 'server');
|
||||
|
||||
if (empty($server)) {
|
||||
$server = common_config('site', 'server');
|
||||
}
|
||||
|
||||
// XXX: protocol
|
||||
|
||||
return 'http://'.$server.$path.$filename;
|
||||
}
|
||||
|
||||
function setDisposition($on, $off, $tile)
|
||||
{
|
||||
if ($on) {
|
||||
$this->disposition |= BACKGROUND_ON;
|
||||
} else {
|
||||
$this->disposition &= ~BACKGROUND_ON;
|
||||
}
|
||||
|
||||
if ($off) {
|
||||
$this->disposition |= BACKGROUND_OFF;
|
||||
} else {
|
||||
$this->disposition &= ~BACKGROUND_OFF;
|
||||
}
|
||||
|
||||
if ($tile) {
|
||||
$this->disposition |= BACKGROUND_TILE;
|
||||
} else {
|
||||
$this->disposition &= ~BACKGROUND_TILE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -62,14 +62,13 @@ class User extends Memcached_DataObject
|
|||
public $autosubscribe; // tinyint(1)
|
||||
public $urlshorteningservice; // varchar(50) default_ur1.ca
|
||||
public $inboxed; // tinyint(1)
|
||||
public $design_id; // int(4)
|
||||
public $viewdesigns; // tinyint(1) default_1
|
||||
public $created; // datetime() not_null
|
||||
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
|
||||
|
||||
/* Static get */
|
||||
function staticGet($k,$v=NULL)
|
||||
{
|
||||
return Memcached_DataObject::staticGet('User',$k,$v);
|
||||
}
|
||||
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('User',$k,$v); }
|
||||
|
||||
/* the code above is auto generated do not remove the tag below */
|
||||
###END_AUTOCODE
|
||||
|
@ -684,4 +683,9 @@ class User extends Memcached_DataObject
|
|||
|
||||
return ($cnt > 0);
|
||||
}
|
||||
|
||||
function getDesign()
|
||||
{
|
||||
return Design::staticGet('id', $this->design_id);
|
||||
}
|
||||
}
|
||||
|
|
15
classes/laconica.ini
Normal file → Executable file
15
classes/laconica.ini
Normal file → Executable file
|
@ -38,6 +38,19 @@ modified = 384
|
|||
[consumer__keys]
|
||||
consumer_key = K
|
||||
|
||||
[design]
|
||||
id = 129
|
||||
backgroundcolor = 1
|
||||
contentcolor = 1
|
||||
sidebarcolor = 1
|
||||
textcolor = 1
|
||||
linkcolor = 1
|
||||
backgroundimage = 2
|
||||
disposition = 17
|
||||
|
||||
[design__keys]
|
||||
id = N
|
||||
|
||||
[fave]
|
||||
notice_id = 129
|
||||
user_id = 129
|
||||
|
@ -430,6 +443,8 @@ uri = 2
|
|||
autosubscribe = 17
|
||||
urlshorteningservice = 2
|
||||
inboxed = 17
|
||||
design_id = 1
|
||||
viewdesigns = 17
|
||||
created = 142
|
||||
modified = 384
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ create table sms_carrier (
|
|||
/* local users */
|
||||
|
||||
create table user (
|
||||
|
||||
id integer primary key comment 'foreign key to profile table' references profile (id),
|
||||
nickname varchar(64) unique key comment 'nickname or username, duped in profile',
|
||||
password varchar(255) comment 'salted password, can be null for OpenID users',
|
||||
|
@ -69,6 +70,9 @@ create table user (
|
|||
autosubscribe tinyint default 0 comment 'automatically subscribe to users who subscribe to us',
|
||||
urlshorteningservice varchar(50) default 'ur1.ca' comment 'service to use for auto-shortening URLs',
|
||||
inboxed tinyint default 0 comment 'has an inbox been created for this user?',
|
||||
design_id integer comment 'id of a design' references design(id),
|
||||
viewdesigns tinyint default 1 comment 'whether to view user-provided designs',
|
||||
|
||||
created datetime not null comment 'date this record was created',
|
||||
modified timestamp comment 'date this record was modified',
|
||||
|
||||
|
@ -484,6 +488,17 @@ create table file_to_post (
|
|||
unique(file_id, post_id)
|
||||
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
create table design (
|
||||
id integer primary key auto_increment comment 'design ID',
|
||||
backgroundcolor integer comment 'main background color',
|
||||
contentcolor integer comment 'content area background color',
|
||||
sidebarcolor integer comment 'sidebar background color',
|
||||
textcolor integer comment 'text color',
|
||||
linkcolor integer comment 'link color',
|
||||
backgroundimage varchar(255) comment 'background image, if any',
|
||||
disposition tinyint default 1 comment 'bit 1 = hide background image, bit 2 = display background image, bit 4 = tile background image'
|
||||
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
|
||||
|
||||
create table group_block (
|
||||
group_id integer not null comment 'group profile is blocked from' references user_group (id),
|
||||
blocked integer not null comment 'profile that is blocked' references profile (id),
|
||||
|
|
|
@ -1,5 +1,21 @@
|
|||
// $Id: farbtastic.js,v 1.2 2007/01/08 22:53:01 unconed Exp $
|
||||
// Farbtastic 1.2
|
||||
/**
|
||||
* Farbtastic Color Picker 1.2
|
||||
* © 2008 Steven Wittens
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
jQuery.fn.farbtastic = function (callback) {
|
||||
$.farbtastic(this, callback);
|
||||
|
|
|
@ -10,19 +10,19 @@ $(document).ready(function() {
|
|||
function UpdateColors(S) {
|
||||
C = $(S).val();
|
||||
switch (parseInt(S.id.slice(-1))) {
|
||||
case 0: default:
|
||||
$('body').css({'background-color':C});
|
||||
break;
|
||||
case 1:
|
||||
$('#content').css({'background-color':C});
|
||||
case 1: default:
|
||||
$('html, body').css({'background-color':C});
|
||||
break;
|
||||
case 2:
|
||||
$('#aside_primary').css({'background-color':C});
|
||||
$('#content, #site_nav_local_views .current a').css({'background-color':C});
|
||||
break;
|
||||
case 3:
|
||||
$('body').css({'color':C});
|
||||
$('#aside_primary').css({'background-color':C});
|
||||
break;
|
||||
case 4:
|
||||
$('html body').css({'color':C});
|
||||
break;
|
||||
case 5:
|
||||
$('a').css({'color':C});
|
||||
break;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ $(document).ready(function() {
|
|||
}
|
||||
}
|
||||
|
||||
function Init() {
|
||||
function InitFarbtastic() {
|
||||
$('#settings_design_color').append('<div id="color-picker"></div>');
|
||||
$('#color-picker').hide();
|
||||
|
||||
|
@ -59,7 +59,9 @@ $(document).ready(function() {
|
|||
swatches
|
||||
.each(SynchColors)
|
||||
.blur(function() {
|
||||
$(this).val($(this).val().toUpperCase());
|
||||
tv = $(this).val();
|
||||
$(this).val(tv.toUpperCase());
|
||||
(tv.length == 4) ? ((tv[0] == '#') ? $(this).val('#'+tv[1]+tv[1]+tv[2]+tv[2]+tv[3]+tv[3]) : '') : '';
|
||||
})
|
||||
.focus(function() {
|
||||
$('#color-picker').show();
|
||||
|
@ -73,13 +75,25 @@ $(document).ready(function() {
|
|||
}
|
||||
|
||||
var f, swatches;
|
||||
Init();
|
||||
InitFarbtastic();
|
||||
$('#form_settings_design').bind('reset', function(){
|
||||
setTimeout(function(){
|
||||
swatches.each(function(){UpdateColors(this);});
|
||||
$('#color-picker').remove();
|
||||
swatches.unbind();
|
||||
Init();
|
||||
InitFarbtastic();
|
||||
},10);
|
||||
});
|
||||
});
|
||||
|
||||
$('#design_background-image_off').focus(function() {
|
||||
$('body').css({'background-image':'none'});
|
||||
});
|
||||
$('#design_background-image_on').focus(function() {
|
||||
var bis = $('#design_background-image_onoff img')[0].src;
|
||||
$('body').css({'background-image':'url('+bis+')'});
|
||||
});
|
||||
|
||||
$('#design_background-image_repeat').click(function() {
|
||||
($(this)[0].checked) ? $('body').css({'background-repeat':'repeat'}) : $('body').css({'background-repeat':'no-repeat'});
|
||||
});
|
||||
});
|
|
@ -235,7 +235,7 @@ $(document).ready(function(){
|
|||
});
|
||||
|
||||
function NoticeReply() {
|
||||
if ($('#notice_data-text').length > 0) {
|
||||
if ($('#notice_data-text').length > 0 && $('#content .notice_reply').length > 0) {
|
||||
$('#content .notice').each(function() {
|
||||
var notice = $(this)[0];
|
||||
$($('.notice_reply', notice)[0]).click(function() {
|
||||
|
@ -308,4 +308,4 @@ function NoticeAttachments() {
|
|||
$(this).closest(".entry-title").removeClass('ov');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ if (!defined('LACONICA')) {
|
|||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
* @see Notice
|
||||
* @see StreamAction
|
||||
* @see NoticeListItem
|
||||
* @see ProfileNoticeList
|
||||
*/
|
||||
|
|
|
@ -71,6 +71,15 @@ $config =
|
|||
array('name' => 'Just another Laconica microblog',
|
||||
'server' => $_server,
|
||||
'theme' => 'default',
|
||||
'skin' => 'default',
|
||||
'design' =>
|
||||
array('backgroundcolor' => '#F0F2F5',
|
||||
'contentcolor' => '#FFFFFF',
|
||||
'sidebarcolor' => '#CEE1E9',
|
||||
'textcolor' => '#000000',
|
||||
'linkcolor' => '#002E6E',
|
||||
'backgroundimage' => null,
|
||||
'disposition' => 1),
|
||||
'path' => $_path,
|
||||
'logfile' => null,
|
||||
'logo' => null,
|
||||
|
@ -111,6 +120,10 @@ $config =
|
|||
array('server' => null,
|
||||
'dir' => INSTALLDIR . '/avatar/',
|
||||
'path' => $_path . '/avatar/'),
|
||||
'background' =>
|
||||
array('server' => null,
|
||||
'dir' => INSTALLDIR . '/background/',
|
||||
'path' => $_path . '/background/'),
|
||||
'public' =>
|
||||
array('localonly' => true,
|
||||
'blacklist' => array(),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* Laconica, the distributed open-source microblogging tool
|
||||
*
|
||||
* User profile page
|
||||
* Base class for actions that use the current user's design
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
|
@ -19,11 +19,10 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Personal
|
||||
* @category Action
|
||||
* @package Laconica
|
||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
||||
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||
* @copyright 2008-2009 Control Yourself, Inc.
|
||||
* @copyright 2009 Control Yourself, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
*/
|
||||
|
@ -33,28 +32,57 @@ if (!defined('LACONICA')) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Base class for user profile page
|
||||
* Base class for actions that use the current user's design
|
||||
*
|
||||
* @category Personal
|
||||
* Some pages (settings in particular) use the current user's chosen
|
||||
* design. This superclass returns that design.
|
||||
*
|
||||
* @category Action
|
||||
* @package Laconica
|
||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
*
|
||||
*/
|
||||
|
||||
class PersonalAction extends Action
|
||||
class CurrentUserDesignAction extends Action
|
||||
{
|
||||
|
||||
var $user = null;
|
||||
/**
|
||||
* Show the user's design stylesheet
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showStylesheets()
|
||||
{
|
||||
parent::showStylesheets();
|
||||
|
||||
function isReadOnly($args)
|
||||
$design = $this->getDesign();
|
||||
|
||||
if (!empty($design)) {
|
||||
$design->showCSS($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A design for this action
|
||||
*
|
||||
* if the user attribute has been set, returns that user's
|
||||
* design.
|
||||
*
|
||||
* @return Design a design object to use
|
||||
*/
|
||||
|
||||
function getDesign()
|
||||
{
|
||||
return true;
|
||||
$cur = common_current_user();
|
||||
|
||||
if (empty($cur)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $cur->getDesign();
|
||||
}
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
}
|
||||
|
||||
}
|
|
@ -27,10 +27,9 @@ require_once INSTALLDIR.'/lib/profilelist.php';
|
|||
|
||||
define('AVATARS_PER_PAGE', 80);
|
||||
|
||||
class GalleryAction extends Action
|
||||
class GalleryAction extends OwnerDesignAction
|
||||
{
|
||||
var $profile = null;
|
||||
var $user = null;
|
||||
var $page = null;
|
||||
var $tag = null;
|
||||
|
||||
|
|
|
@ -31,8 +31,6 @@ if (!defined('LACONICA')) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/personal.php';
|
||||
|
||||
define('MESSAGES_PER_PAGE', 20);
|
||||
|
||||
/**
|
||||
|
@ -47,11 +45,11 @@ define('MESSAGES_PER_PAGE', 20);
|
|||
* @see OutboxAction
|
||||
*/
|
||||
|
||||
class MailboxAction extends PersonalAction
|
||||
class MailboxAction extends CurrentUserDesignAction
|
||||
{
|
||||
var $page = null;
|
||||
|
||||
function prepare($args)
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
|
@ -265,12 +263,12 @@ class MailboxAction extends PersonalAction
|
|||
* Returns either the name (and link) of the API client that posted the notice,
|
||||
* or one of other other channels.
|
||||
*
|
||||
* @param string $source the source of the message
|
||||
* @param string $source the source of the message
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function showSource($source)
|
||||
function showSource($source)
|
||||
{
|
||||
$source_name = _($source);
|
||||
switch ($source) {
|
||||
|
@ -297,4 +295,17 @@ class MailboxAction extends PersonalAction
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mailbox actions are read only
|
||||
*
|
||||
* @param array $args other arguments
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
function isReadOnly($args)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ require_once INSTALLDIR.'/lib/attachmentlist.php';
|
|||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
* @see Notice
|
||||
* @see StreamAction
|
||||
* @see NoticeListItem
|
||||
* @see ProfileNoticeList
|
||||
*/
|
||||
|
|
88
lib/ownerdesignaction.php
Normal file
88
lib/ownerdesignaction.php
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
/**
|
||||
* Laconica, the distributed open-source microblogging tool
|
||||
*
|
||||
* Base class for actions that use the page owner's design
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Action
|
||||
* @package Laconica
|
||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
||||
* @copyright 2009 Control Yourself, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
*/
|
||||
|
||||
if (!defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for actions that use the page owner's design
|
||||
*
|
||||
* Some pages have a clear "owner" -- like the profile page, subscriptions
|
||||
* pages, etc. This superclass uses that owner's chosen design for the page
|
||||
* design.
|
||||
*
|
||||
* @category Action
|
||||
* @package Laconica
|
||||
* @author Evan Prodromou <evan@controlyourself.ca>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
*
|
||||
*/
|
||||
|
||||
class OwnerDesignAction extends Action {
|
||||
|
||||
/** The user for this page. */
|
||||
|
||||
var $user = null;
|
||||
|
||||
/**
|
||||
* Show the owner's design stylesheet
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
function showStylesheets()
|
||||
{
|
||||
parent::showStylesheets();
|
||||
|
||||
$design = $this->getDesign();
|
||||
|
||||
if (!empty($design)) {
|
||||
$design->showCSS($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A design for this action
|
||||
*
|
||||
* if the user attribute has been set, returns that user's
|
||||
* design.
|
||||
*
|
||||
* @return Design a design object to use
|
||||
*/
|
||||
|
||||
function getDesign()
|
||||
{
|
||||
if (empty($this->user)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->user->getDesign();
|
||||
}
|
||||
}
|
|
@ -47,9 +47,8 @@ require_once INSTALLDIR.'/lib/groupminilist.php';
|
|||
* @link http://laconi.ca/
|
||||
*/
|
||||
|
||||
class ProfileAction extends Action
|
||||
class ProfileAction extends OwnerDesignAction
|
||||
{
|
||||
var $user = null;
|
||||
var $page = null;
|
||||
var $profile = null;
|
||||
var $tag = null;
|
||||
|
|
|
@ -43,7 +43,7 @@ if (!defined('LACONICA')) {
|
|||
* @see Widget
|
||||
*/
|
||||
|
||||
class SettingsAction extends Action
|
||||
class SettingsAction extends CurrentUserDesignAction
|
||||
{
|
||||
/**
|
||||
* A message for the user.
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Laconica - a distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, Controlez-Vous, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('LACONICA')) { exit(1); }
|
||||
|
||||
require_once(INSTALLDIR.'/lib/personal.php');
|
||||
require_once(INSTALLDIR.'/lib/noticelist.php');
|
||||
|
||||
class StreamAction extends PersonalAction
|
||||
{
|
||||
function show_notice_list($notice)
|
||||
{
|
||||
$nl = new NoticeList($notice);
|
||||
return $nl->show();
|
||||
}
|
||||
}
|
192
lib/webcolor.php
Normal file
192
lib/webcolor.php
Normal file
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
/**
|
||||
* Laconica, the distributed open-source microblogging tool
|
||||
*
|
||||
* Base class for deleting things
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Personal
|
||||
* @package Laconica
|
||||
* @author Zach Copley <zach@controlyourself.ca>
|
||||
* @copyright 2009 Control Yourself, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://laconi.ca/
|
||||
*/
|
||||
|
||||
if (!defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
class WebColor {
|
||||
|
||||
// XXX: Maybe make getters and setters for r,g,b values and tuples,
|
||||
// e.g.: to support this kinda CSS representation: rgb(255,0,0)
|
||||
// http://www.w3.org/TR/CSS21/syndata.html#color-units
|
||||
|
||||
var $red = 0;
|
||||
var $green = 0;
|
||||
var $blue = 0;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function __construct($color = null)
|
||||
{
|
||||
if (isset($color)) {
|
||||
$this->parseColor($color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses input to and tries to determine whether the color
|
||||
* is being specified via an integer or hex tuple and sets
|
||||
* the RGB instance variables accordingly.
|
||||
*
|
||||
* XXX: Maybe support (r,g,b) style, and array?
|
||||
*
|
||||
* @param mixed $color
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function parseColor($color) {
|
||||
|
||||
if (is_numeric($color)) {
|
||||
$this->setIntColor($color);
|
||||
} else {
|
||||
|
||||
// XXX named colors
|
||||
|
||||
// XXX: probably should do even more validation
|
||||
|
||||
if (preg_match('/(#([0-9A-Fa-f]{3,6})\b)/u', $color) > 0) {
|
||||
$this->setHexColor($color);
|
||||
} else {
|
||||
$errmsg = _('%s is not a valid color!');
|
||||
throw new WebColorException(sprintf($errmsg, $color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function setNamedColor($name)
|
||||
{
|
||||
// XXX Implement this
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the RGB color values from a a hex tuple
|
||||
*
|
||||
* @param string $hexcolor
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function setHexColor($hexcolor) {
|
||||
|
||||
if ($hexcolor[0] == '#') {
|
||||
$hexcolor = substr($hexcolor, 1);
|
||||
}
|
||||
|
||||
if (strlen($hexcolor) == 6) {
|
||||
list($r, $g, $b) = array($hexcolor[0].$hexcolor[1],
|
||||
$hexcolor[2].$hexcolor[3],
|
||||
$hexcolor[4].$hexcolor[5]);
|
||||
} elseif (strlen($hexcolor) == 3) {
|
||||
list($r, $g, $b) = array($hexcolor[0].$hexcolor[0],
|
||||
$hexcolor[1].$hexcolor[1],
|
||||
$hexcolor[2].$hexcolor[2]);
|
||||
} else {
|
||||
$errmsg = _('%s is not a valid color! Use 3 or 6 hex chars.');
|
||||
throw new WebColorException(sprintf($errmsg, $hexcolor));
|
||||
}
|
||||
|
||||
$this->red = hexdec($r);
|
||||
$this->green = hexdec($g);
|
||||
$this->blue = hexdec($b);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RGB color values from a 24-bit integer
|
||||
*
|
||||
* @param int $intcolor
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
|
||||
function setIntColor($intcolor)
|
||||
{
|
||||
// We could do 32 bit and have an alpha channel because
|
||||
// Sarven wants one real bad, but nah.
|
||||
|
||||
$this->red = $intcolor >> 16;
|
||||
$this->green = $intcolor >> 8 & 0xFF;
|
||||
$this->blue = $intcolor & 0xFF;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hex tuple of the RGB color useful for output in HTML
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
function hexValue() {
|
||||
|
||||
$hexcolor = (strlen(dechex($this->red)) < 2 ? '0' : '' ) .
|
||||
dechex($this->red);
|
||||
$hexcolor .= (strlen(dechex($this->green)) < 2 ? '0' : '') .
|
||||
dechex($this->green);
|
||||
$hexcolor .= (strlen(dechex($this->blue)) < 2 ? '0' : '') .
|
||||
dechex($this->blue);
|
||||
|
||||
return strtoupper($hexcolor);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a 24-bit packed integer representation of the RGB color
|
||||
* for convenient storage in the DB
|
||||
*
|
||||
* XXX: probably could just use hexdec() instead
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
||||
function intValue()
|
||||
{
|
||||
$intcolor = 256 * 256 * $this->red + 256 * $this->green + $this->blue;
|
||||
return $intcolor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WebColorException extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
|
@ -12,9 +12,9 @@ img { display:block; border:0; }
|
|||
a abbr { cursor: pointer; border-bottom:0; }
|
||||
table { border-collapse:collapse; }
|
||||
ol { list-style-position:inside; }
|
||||
html { font-size: 87.5%; background-color:#fff; height:100%; }
|
||||
html { font-size: 87.5%; height:100%; }
|
||||
body {
|
||||
background-color:#fff;
|
||||
background-color:#FFFFFF;
|
||||
color:#000;
|
||||
font-family:sans-serif;
|
||||
font-size:1em;
|
||||
|
@ -77,7 +77,8 @@ margin:0 0 18px 0;
|
|||
form label {
|
||||
font-weight:bold;
|
||||
}
|
||||
input.checkbox {
|
||||
input.checkbox,
|
||||
input.radio {
|
||||
position:relative;
|
||||
top:2px;
|
||||
left:0;
|
||||
|
@ -169,7 +170,8 @@ margin-bottom:0;
|
|||
margin-bottom:11px;
|
||||
}
|
||||
|
||||
.form_settings input.checkbox {
|
||||
.form_settings input.checkbox,
|
||||
.form_settings input.radio {
|
||||
margin-top:3px;
|
||||
margin-left:0;
|
||||
}
|
||||
|
@ -181,13 +183,19 @@ margin-left:11px;
|
|||
float:left;
|
||||
width:90%;
|
||||
}
|
||||
|
||||
.form_settings label.radio {
|
||||
margin-top:0;
|
||||
margin-right:47px;
|
||||
margin-left:11px;
|
||||
width:auto;
|
||||
}
|
||||
|
||||
#form_login p.form_guide,
|
||||
#form_register #settings_rememberme p.form_guide,
|
||||
#form_openid_login #settings_rememberme p.form_guide,
|
||||
#settings_twitter_remove p.form_guide,
|
||||
#form_search ul.form_data #q {
|
||||
#form_search ul.form_data #q,
|
||||
#design_background-image_onoff p.form_guide {
|
||||
margin-left:0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* IE specific styles */
|
||||
legend {
|
||||
margin-left:-7px;
|
||||
}
|
||||
input.checkbox {
|
||||
input.checkbox,
|
||||
input.radio {
|
||||
top:0;
|
||||
}
|
||||
#form_notice textarea {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
@import url(../../base/css/display.css);
|
||||
|
||||
html,
|
||||
body,
|
||||
a:active {
|
||||
background-color:#C3D6DF;
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
@import url(../../base/css/display.css);
|
||||
|
||||
html,
|
||||
body,
|
||||
a:active {
|
||||
background-color:#F0F2F5;
|
||||
|
|
Loading…
Reference in New Issue
Block a user