Skip to content

Commit

Permalink
User shares: Show avatars
Browse files Browse the repository at this point in the history
[Sharing] Show placeholders for avatars

Just like on the web show placeholders for avatars in the sharing dialog

[Sharing] Show avatars!

[Sharing] Show same avatar placeholder for group/federated shares as on
web
  • Loading branch information
rullzer authored and ckamm committed Nov 20, 2017
1 parent aafe7c4 commit e9f7485
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ set(client_SRCS
accountmanager.cpp
accountsettings.cpp
application.cpp
avatarjob.cpp
folder.cpp
folderman.cpp
folderstatusmodel.cpp
Expand Down
52 changes: 52 additions & 0 deletions src/gui/avatarjob.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) by Roeland Jago Douma <[email protected]>
*
* 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; version 2 of the License.
*
* 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.
*/

#include "avatarjob.h"
#include "networkjobs.h"
#include "account.h"

#include <QLatin1String>

namespace OCC {

AvatarJob2::AvatarJob2(const QString &userId, int size, AccountPtr account, QObject* parent)
: AbstractNetworkJob(account, QLatin1String("remote.php/dav/avatars/"), parent)
{
setIgnoreCredentialFailure(true);

//Append <userid>/<size> to the path
setPath(path() + userId + QString("/%1").arg(size));
}

void AvatarJob2::start()
{
sendRequest("GET", Utility::concatUrlPath(account()->url(), path()));
AbstractNetworkJob::start();
}

bool AvatarJob2::finished()
{
int statusCode = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

if (statusCode != 200) {
emit avatarNotAvailable(statusCode);
} else {
QByteArray data = reply()->readAll();
QString mimeType = reply()->header(QNetworkRequest::ContentTypeHeader).toString();
emit avatarReady(data, mimeType);
}

return true;
}

}
63 changes: 63 additions & 0 deletions src/gui/avatarjob.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (C) by Roeland Jago Douma <[email protected]>
*
* 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; version 2 of the License.
*
* 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.
*/

#ifndef AVATARJOB_H
#define AVATARJOB_H

#include "networkjobs.h"
#include "accountfwd.h"

namespace OCC {

/**
* @brief Job to fetch an avatar for a user
* @ingroup gui
*/
class AvatarJob2 : public AbstractNetworkJob {
Q_OBJECT
public:
/**
* @param userId The user for which to obtain the avatar
* @param size The size of the avatar (square so size*size)
* @param account For which account to obtain the avatar
* @param parent Parent of the object
*/
explicit AvatarJob2(const QString& userId, int size, AccountPtr account, QObject* parent = 0);

public slots:
/* Start the job */
void start() Q_DECL_OVERRIDE;
signals:
/**
* Signal that the job is done and returned an avatar
*
* @param reply the content of the reply
* @param the mimetype (set by the server)
*/
void avatarReady(QByteArray reply, QString mimeType);

/**
* Signal that the job is done but the server did not return
* an avatar
*
* @param statusCode The status code returned by the server
*/
void avatarNotAvailable(int statusCode);

private slots:
virtual bool finished() Q_DECL_OVERRIDE;
};

}

#endif // AVATAR_H
101 changes: 101 additions & 0 deletions src/gui/shareusergroupwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "thumbnailjob.h"
#include "sharee.h"
#include "sharemanager.h"
#include "avatarjob.h"

#include "QProgressIndicator.h"
#include <QBuffer>
Expand All @@ -41,6 +42,9 @@
#include <QAction>
#include <QDesktopServices>
#include <QMessageBox>
#include <QCryptographicHash>
#include <QColor>
#include <QPainter>

namespace OCC {

Expand Down Expand Up @@ -416,6 +420,103 @@ ShareUserLine::ShareUserLine(QSharedPointer<Share> share,
if (!share->account()->capabilities().shareResharing()) {
_ui->permissionShare->hide();
}

loadAvatar();
}

void ShareUserLine::loadAvatar()
{
/* Set the default place holder
* This is calculated the same way as on the webinterface
* So that the colors match
*
* This is done first so that we can directly show something
*/

// Set size of the placeholder
_ui->avatar->setMinimumHeight(48);
_ui->avatar->setMinimumWidth(48);
_ui->avatar->setMaximumHeight(48);
_ui->avatar->setMaximumWidth(48);
_ui->avatar->setAlignment(Qt::AlignCenter);

/* Calculate the hue
* We could use more digits but we have the MSB now which
* is already plenty
*/
const QString text = _share->getShareWith()->displayName();

QString seed = _share->getShareWith()->shareWith();
if (_share->getShareWith()->type() != Sharee::User) {
seed += QString(" %1").arg(_share->getShareWith()->type());
}

const QByteArray hash = QCryptographicHash::hash(seed.toUtf8(), QCryptographicHash::Md5);
int hue = ((double)hash.mid(0, 3).toHex().toInt(0, 16) / (double)0xffffff) * 255;

const QColor bg = QColor::fromHsl(hue, 230, 166);
const QString style = QString("* {\
color: #fff;\
background-color: %1;\
border-radius: 24px;\
font-size: 26px\
}").arg(bg.name());

// Set the style
_ui->avatar->setStyleSheet(style);

// Set the placeholder text
_ui->avatar->setText(text.at(0).toUpper());

// We can only fetch avatars for local users currently
if (_share->getShareWith()->type() == Sharee::User) {
AvatarJob2 *job = new AvatarJob2(_share->getShareWith()->shareWith(), 48, _share->account(), this);
connect(job, SIGNAL(avatarReady(QByteArray, QString)), SLOT(slotAvatarLoaded(QByteArray, QString)));
job->start();
}
}

void ShareUserLine::slotAvatarLoaded(const QByteArray &data, const QString &mimeType)
{
QPixmap p;
bool valid = false;
if (mimeType == "image/png") {
valid = p.loadFromData(data, "PNG");
} else if (mimeType == "image/jpeg") {
valid = p.loadFromData(data, "JPG");
} else {
// Guess the filetype
valid = p.loadFromData(data);
}

// If the image was loaded succesfully set it!
if (valid) {

/*
* We want round avatars so create a new pixmap to draw
* the round avatar on and set a transparent background
*/
QPixmap avatar(p.width(), p.height());
avatar.fill(QColor(0,0,0,0));

// Initialise our painer
QPainter painter(&avatar);
painter.setRenderHint(QPainter::Antialiasing);

// Set to draw only a cricle
QPainterPath path;
path.addEllipse(0,0,p.width(),p.height());
painter.setClipPath(path);

// Draw the round avatar
painter.drawPixmap(0,0,p.width(),p.width(),p);

// Set the avatar
_ui->avatar->setPixmap(avatar);

// Remove the stylesheet
_ui->avatar->setStyleSheet("");
}
}

void ShareUserLine::on_deleteShareButton_clicked()
Expand Down
3 changes: 3 additions & 0 deletions src/gui/shareusergroupwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,11 @@ private slots:
void slotShareDeleted();
void slotPermissionsSet();

void slotAvatarLoaded(const QByteArray &data, const QString &mimeType);

private:
void displayPermissions();
void loadAvatar();

Ui::ShareUserLine *_ui;
QSharedPointer<Share> _share;
Expand Down
7 changes: 7 additions & 0 deletions src/gui/shareuserline.ui
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="avatar">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="sharedWith">
<property name="text">
Expand Down

0 comments on commit e9f7485

Please sign in to comment.