git.gnu.io has moved to IP address 209.51.188.249 -- please double check where you are logging in.

Commit 2950f0a2 authored by hannes's avatar hannes

v4. design, img upload, avatar, bg img, etc etc

parent 525124f1
......@@ -39,7 +39,7 @@ class QvitterPlugin extends Plugin {
public function settings($setting)
{
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· S E T T I N G S ·
· ·
......@@ -101,7 +101,17 @@ class QvitterPlugin extends Plugin {
array('action' => 'apiqvitterallfollowing',
'id' => Nickname::INPUT_FMT));
$m->connect('api/qvitter/update_cover_photo.json',
array('action' => 'ApiUpdateCoverPhoto'));
array('action' => 'ApiUpdateCoverPhoto'));
$m->connect('api/qvitter/update_background_image.json',
array('action' => 'ApiUpdateBackgroundImage'));
$m->connect('api/qvitter/update_avatar.json',
array('action' => 'ApiUpdateAvatar'));
$m->connect('api/qvitter/upload_image.json',
array('action' => 'ApiUploadImage'));
$m->connect('api/qvitter/external_user_show.json',
array('action' => 'ApiExternalUserShow'));
$m->connect('api/qvitter/toggle_qvitter.json',
array('action' => 'ApiToggleQvitter'));
$m->connect('api/qvitter/statuses/notifications.json',
array('action' => 'apiqvitternotifications'));
$m->connect(':nickname/notifications',
......@@ -206,6 +216,165 @@ class QvitterPlugin extends Plugin {
}
/**
* Add script to default ui, to be able to toggle Qvitter with one click
*
* @return boolean hook return
*/
function onEndShowScripts($action){
if (common_logged_in()) {
$user = common_current_user();
$profile = $user->getProfile();
$qvitter_enabled='false';
// if qvitter is enabled by default but _not_ disabled by the user,
if(QvitterPlugin::settings('enabledbydefault')) {
$disabled = Profile_prefs::getConfigData($profile, 'qvitter', 'disable_qvitter');
if($disabled == 0) {
$qvitter_enabled='true';
}
}
// if qvitter is disabled by default and _enabled_ by the user,
else {
$enabled = Profile_prefs::getConfigData($profile, 'qvitter', 'enable_qvitter');
if($enabled == 1) {
$qvitter_enabled='true';
}
}
$action->inlineScript('var toggleQvitterAPIURL = \''.common_path('', true).'api/qvitter/toggle_qvitter.json\'; var toggleText = \'New '.str_replace("'","\'",common_config('site','name')).'\';var qvitterEnabled = '.$qvitter_enabled.';');
$action->script($this->path('js/toggleqvitter.js'));
}
}
/**
* User colors in default UI too, if theme is neo-quitter
*
* @return boolean hook return
*/
function onEndShowStylesheets($action) {
$theme = common_config('site','theme');
if (common_logged_in() && substr($theme,0,11) == 'neo-quitter') {
$user = common_current_user();
$profile = $user->getProfile();
$backgroundcolor = Profile_prefs::getConfigData($profile, 'theme', 'backgroundcolor');
if(!$backgroundcolor) {
$backgroundcolor = substr(QvitterPlugin::settings('defaultbackgroundcolor'),1);
}
$linkcolor = Profile_prefs::getConfigData($profile, 'theme', 'linkcolor');
if(!$linkcolor) {
$linkcolor = substr(QvitterPlugin::settings('defaultlinkcolor'),1);
}
$ligthen_elements = '';
if($this->darkness($backgroundcolor)<0.5) {
$ligthen_elements = "
#nav_profile a:before,
#nav_timeline_replies a:before,
#nav_timeline_personal a:before,
#nav_local_default li:first-child ul.nav li:nth-child(4) a:before,
#nav_timeline_favorites a:before,
#nav_timeline_public a:before,
#nav_groups a:before,
#nav_recent-tags a:before,
#nav_timeline_favorited a:before,
#nav_directory a:before,
#nav_lists a:before,
#site_nav_local_views h3,
#content h1,
#aside_primary h2,
#gnusocial-version p,
#page_notice,
#pagination .nav_next a {
color:rgba(255,255,255,0.4);
}
.nav li.current a:before,
.entity_actions a {
color: rgba(255,255,255, 0.6) !important;
}
#aside_primary,
.entity_edit a:before,
.entity_remote_subscribe:before,
#export_data a:before,
.peopletags_edit_button:before,
.form_group_join:before,
.form_group_leave:before,
.form_group_delete:before,
#site_nav_object li.current a,
#pagination .nav_next a:hover,
#content .guide {
color: rgba(255,255,255, 0.6);
}
#site_nav_local_views a,
#site_nav_object a,
#aside_primary a:not(.invite_button) {
color: rgba(255,255,255, 0.7);
}
#site_nav_local_views li.current a,
.entity_edit a:hover:before,
.entity_remote_subscribe:hover:before,
.peopletags_edit_button:hover:before,
.form_group_join:hover:before,
.form_group_leave:hover:before,
.form_group_delete:hover:before {
color: rgba(255,255,255, 0.8);
}
#site_nav_local_views li.current a {
background-position: -3px 1px;
}
#site_nav_local_views li a:hover {
background-position:-3px -24px;
}
#gnusocial-version,
#pagination .nav_next a {
border-color: rgba(255,255,255, 0.3);
}
#pagination .nav_next a:hover {
border-color: rgba(255,255,255, 0.5);
}
#site_nav_object li.current a {
background-position: -3px 2px;
}
#site_nav_object li a:hover {
background-position: -3px -23px;
}
";
}
$action->style("
body {
background-color:#".$backgroundcolor.";
}
a,
a:hover,
a:active,
#site_nav_global_primary a:hover,
.threaded-replies .notice-faves:before,
.threaded-replies .notice-repeats:before,
.notice-reply-comments > a:before {
color:#".$linkcolor.";
}
#site_nav_global_primary a:hover {
border-color:#".$linkcolor.";
}
address {
background-color:#".$linkcolor.";
}
".$ligthen_elements);
}
}
/**
* Menu item for Qvitter
*
......@@ -269,13 +438,13 @@ class QvitterPlugin extends Plugin {
$notice_groups = $notice->getGroups();
$group_addressees = false;
foreach($notice_groups as $g) {
$group_addressees .= '!'.$g->nickname.' ';
}
$group_addressees = trim($group_addressees);
if($group_addressees == '') $group_addressees = false;
error_log(print_r($g,true));
$group_addressees = array('nickname'=>$g->nickname,'url'=>$g->mainpage);
}
$twitter_status['statusnet_in_groups'] = $group_addressees;
// thumb urls
// find all thumbs
......@@ -303,13 +472,39 @@ class QvitterPlugin extends Plugin {
}
}
}
// reply-to profile url
if ($notice->reply_to) {
$reply = Notice::getKV(intval($notice->reply_to));
if ($reply) {
$replier_profile = $reply->getProfile();
}
}
$twitter_status['in_reply_to_profileurl'] =
($replier_profile) ? $replier_profile->profileurl : null;
// some more metadata about notice
if($notice->is_local == '1') {
$twitter_status['is_local'] = true;
}
else {
$twitter_status['is_local'] = false;
$twitter_status['external_url'] = $notice->url;
}
if($notice->object_type == 'activity') {
$twitter_status['is_activity'] = true;
}
else {
$twitter_status['is_activity'] = false;
}
return true;
}
/**
* Cover photo in API response, also follows_you
* Cover photo in API response, also follows_you, etc
*
* @return boolean hook return
*/
......@@ -318,11 +513,16 @@ class QvitterPlugin extends Plugin {
{
$twitter_user['cover_photo'] = Profile_prefs::getConfigData($profile, 'qvitter', 'cover_photo');
$twitter_user['background_image'] = Profile_prefs::getConfigData($profile, 'qvitter', 'background_image');
// follows me?
if ($scoped) {
$twitter_user['follows_you'] = $profile->isSubscribed($scoped);
}
// local user?
$twitter_user['is_local'] = $profile->isLocal();
return true;
......@@ -486,6 +686,24 @@ class QvitterPlugin extends Plugin {
return true;
}
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'Qvitter',
'version' => '4',
'author' => 'Hannes Mannerheim',
'homepage' => 'https://github.com/hannesmannerheim/qvitter',
'rawdescription' => _m('User interface'));
return true;
}
function darkness($hex) {
$r = hexdec($hex[0].$hex[1]);
$g = hexdec($hex[2].$hex[3]);
$b = hexdec($hex[4].$hex[5]);
return (max($r, $g, $b) + min($r, $g, $b)) / 510.0; // HSL algorithm
}
}
......
......@@ -2,8 +2,8 @@ Qvitter
==========================================
* Author: Hannes Mannerheim (<h@nnesmannerhe.im>)
* Last mod.: Sept, 2014
* Version: 3
* Last mod.: Nov, 2014
* Version: 4
* GitHub: <https://github.com/hannesmannerheim/qvitter>
Qvitter is free software: you can redistribute it and / or modify it
......@@ -44,19 +44,13 @@ Note: Qvitter is tested with GNU Social version 1.1.1-alpha2 (7e47026085fa4f2071
TODO
----
1. image attachments
1. avatar upload from profile card
1. better user popup, with e.g. latest queets
1. Faq
1. rtl is a little broken, also mobile rtl
1. DM's
1. lists
1. user actions-cog wheel in users lists, ellipsis button in queets, with block etc
1. user actions-cog wheel in users lists, with block, list etc
1. lists
1. proxy to non-https for getting conversations the instance doesn't have via jsonp
......@@ -66,8 +60,6 @@ TODO
2. Creating groups, make admin, block user
7. Settings (e.g. don't show replies to people I don't follow)
10. Search users
11. Recommended users
......
<?php
/**
* StatusNet, the distributed open-source microblogging tool
*
* Show an external user's profile information
*
* 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 API
* @package GNUsocial
* @author Hannes Mannerheim <h@nnesmannerhe.im>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Ouputs information for a user, specified by ID or screen name.
* The user's most recent status will be returned inline.
*/
class ApiExternalUserShowAction extends ApiPrivateAuthAction
{
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$profileurl = urldecode($this->arg('profileurl'));
// if this is an instance/user/1234 type url, try to find real profile url
if(strstr($profileurl, '/user/')) {
$redrected_profileurl = $this->getRedirectUrl($profileurl);
// if there's multiple redirects the _first_ redirect is most likely to be the real profileurl
if(is_array($redrected_profileurl)) {
$profileurl = $redrected_profileurl[0];
}
// if only one redirect
elseif($redrected_profileurl !== false) {
$profileurl = $redrected_profileurl;
}
}
// get local profile
$local_profile = Profile::getKV('profileurl',$profileurl);
if($local_profile) {
$this->profile->local = $this->twitterUserArray($local_profile);
}
// get profile from external instance
$instanceurl = substr($profileurl, 0, strrpos($profileurl, '/'));
$username = substr($profileurl, strrpos($profileurl, '/')+1);
$apicall = $instanceurl.'/api/users/show.json?id='.$username;
stream_context_set_default(array('http' => array('method' => 'GET')));
$this->profile->external = json_decode(file_get_contents($apicall));
return true;
}
/**
* Handle the request
*
* Check the format and show the user info
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$this->initDocument('json');
$this->showJsonObjects($this->profile);
$this->endDocument('json');
}
/**
* Return true if read only.
*
* MAY override
*
* @param array $args other arguments
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
}
/**
* Get redirect(s) for an url
*
*/
function getRedirectUrl ($url) {
stream_context_set_default(array(
'http' => array(
'method' => 'HEAD'
)
));
$headers = get_headers($url, 1);
if ($headers !== false && isset($headers['Location'])) {
return $headers['Location'];
}
return false;
}
}
......@@ -77,6 +77,9 @@ class ApiQvitterUpdateBackgroundColorAction extends ApiAuthAction
}
Profile_prefs::setData($this->scoped, 'theme', 'backgroundcolor', $this->backgroundcolor);
// unset background-image
Profile_prefs::setData($this->scoped, 'qvitter', 'background_image', '');
$twitter_user = $this->twitterUserArray($this->scoped, true);
......
<?php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· ·
· Qvitter 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 three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
· ·
· Contact h@nnesmannerhe.im if you have any questions. ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiToggleQvitterAction extends ApiAuthAction
{
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
return true;
}
/**
* Handle the request
*
* Try to save the user's colors in her design. Create a new design
* if the user doesn't already have one.
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$user = common_current_user();
$profile = $user->getProfile();
if(QvitterPlugin::settings('enabledbydefault')) {
$state = Profile_prefs::getConfigData($profile, 'qvitter', 'disable_qvitter');
if($state == 1) {
Profile_prefs::setData($profile, 'qvitter', 'disable_qvitter', 0);
}
else {
Profile_prefs::setData($profile, 'qvitter', 'disable_qvitter', 1);
}
}
else {
$state = Profile_prefs::getConfigData($profile, 'qvitter', 'enable_qvitter');
if($state == 1) {
Profile_prefs::setData($profile, 'qvitter', 'enable_qvitter', 0);
}
else {
Profile_prefs::setData($profile, 'qvitter', 'enable_qvitter', 1);
}
}
$result['success'] = true;
$this->initDocument('json');
$this->showJsonObjects($result);
$this->endDocument('json');
}
}
<?php
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
· ·
· Update the avatar
· ·
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· Qvitter 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 three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY 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 Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
· ·
· Contact h@nnesmannerhe.im if you have any questions. ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
if (!defined('GNUSOCIAL')) {
exit(1);
}
class ApiUpdateAvatarAction extends ApiAuthAction
{
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->user = $this->auth_user;
$this->cropW = $this->trimmed('cropW');
$this->cropH = $this->trimmed('cropH');
$this->cropX = $this->trimmed('cropX');
$this->cropY = $this->trimmed('cropY');
$this->img = $this->trimmed('img');
return true;
}
/**
* Handle the request
*
* @return void
*/
protected function handle()
{
parent::handle();
$profile = $this->user->getProfile();
$base64img = $this->img;
if(stristr($base64img, 'image/jpeg')) {
$base64img_mime = 'image/jpeg';
}
elseif(stristr($base64img, 'image/png')) {
// should convert to jpg here!!
$base64img_mime = 'image/png';
}
$base64img = str_replace('data:image/jpeg;base64,', '', $base64img);
$base64img = str_replace('data:image/png;base64,', '', $base64img);
$base64img = str_replace(' ', '+', $base64img);
$base64img_hash = md5($base64img);
$base64img = base64_decode($base64img);
$base64img_basename = basename('avatar');
$base64img_filename = File::filename($profile, $base64img_basename, $base64img_mime);
$base64img_path = File::path($base64img_filename);
$base64img_success = file_put_contents($base64img_path, $base64img);
$base64img_mimetype = MediaFile::getUploadedMimeType($base64img_path, $base64img_filename);
$mediafile = new MediaFile($profile, $base64img_filename, $base64img_mimetype);
$imagefile = new ImageFile($mediafile->fileRecord->id, File::path($mediafile->filename));
$imagefile->resizeTo(File::path($mediafile->filename), array('width'=>$this->cropW, 'height'=>$this->cropH, 'x'=>$this->cropX, 'y'=>$this->cropY, 'w'=>$this->cropW, 'h'=>$this->cropH));
$type = $imagefile->preferredType();
$filename = Avatar::filename(
$profile->id,
image_type_to_extension($type),
null,
common_timestamp()
);
$filepath = Avatar::path($filename);
$imagefile->copyTo($filepath);
$profile = $this->user->getProfile();
$profile->setOriginal($filename);
$mediafile->delete();
$twitter_user = $this->twitterUserArray($profile, true);
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}
<?php
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
· ·
· Update the cover photo ·
· ·
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· Qvitter 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 three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·