diff --git a/retroshare-gui/src/gui/People/PeopleDialog.cpp b/retroshare-gui/src/gui/People/PeopleDialog.cpp index ad7c955de..1918035ca 100644 --- a/retroshare-gui/src/gui/People/PeopleDialog.cpp +++ b/retroshare-gui/src/gui/People/PeopleDialog.cpp @@ -126,6 +126,10 @@ PeopleDialog::PeopleDialog(QWidget *parent) reloadAll(); + mCurrentViewMode = VIEW_MODE_LIST; + mSearchFilter.clear(); + mSortMethod = 0; + } /** Destructor. */ @@ -1121,3 +1125,102 @@ void PeopleDialog::populatePictureFlowInt() }//for (it=_int_circles_widgets.begin(); it!=_int_circles_widgets.end(); ++it) pictureFlowWidgetInternal->setSlideSizeRatio(4/4.0); } + +void PeopleDialog::on_listViewButton_toggled(bool checked) +{ + if (checked) { + thumbnailViewButton->setChecked(false); + setViewMode(VIEW_MODE_LIST); + } +} + +void PeopleDialog::on_thumbnailViewButton_toggled(bool checked) +{ + if (checked) { + listViewButton->setChecked(false); + setViewMode(VIEW_MODE_THUMBNAIL); + } +} + +void PeopleDialog::on_searchPeopleLineEdit_textChanged(const QString &text) +{ + mSearchFilter = text; + filterIdentities(); +} + +void PeopleDialog::on_sortPeopleComboBox_currentIndexChanged(int index) +{ + mSortMethod = index; + sortIdentities(); +} + +void PeopleDialog::setViewMode(int mode) +{ + mCurrentViewMode = mode; + Settings->setValueToGroup("PeopleDialog", "ViewMode", mode); + setIdentitiesViewMode(mode); +} + +void PeopleDialog::filterIdentities() +{ + std::map::iterator itExt; + for (itExt = _gxs_identity_widgets.begin(); itExt != _gxs_identity_widgets.end(); ++itExt) { + IdentityWidget *widget = itExt->second; + if (mSearchFilter.isEmpty()) { + widget->setVisible(true); + } else { + widget->setVisible(true); + } + } + + std::map::iterator itInt; + for (itInt = _pgp_identity_widgets.begin(); itInt != _pgp_identity_widgets.end(); ++itInt) { + IdentityWidget *widget = itInt->second; + if (mSearchFilter.isEmpty()) { + widget->setVisible(true); + } else { + widget->setVisible(true); + } + } +} + +void PeopleDialog::sortIdentities() +{ + // Placeholder for sorting implementation +} + +void PeopleDialog::setIdentitiesViewMode(int mode) +{ + // Apply thumbnail/list mode to all identity widgets + // This changes the visual presentation of each IdentityWidget + + if (mode == VIEW_MODE_THUMBNAIL) { + // In thumbnail mode, minimize labels and show compact view + std::map::iterator itExt; + for (itExt = _gxs_identity_widgets.begin(); itExt != _gxs_identity_widgets.end(); ++itExt) { + IdentityWidget *widget = itExt->second; + widget->setMinimumSize(QSize(80, 80)); + widget->setMaximumSize(QSize(80, 80)); + } + std::map::iterator itInt; + for (itInt = _pgp_identity_widgets.begin(); itInt != _pgp_identity_widgets.end(); ++itInt) { + IdentityWidget *widget = itInt->second; + widget->setMinimumSize(QSize(80, 80)); + widget->setMaximumSize(QSize(80, 80)); + } + } else { + // List mode - restore normal size + std::map::iterator itExt; + for (itExt = _gxs_identity_widgets.begin(); itExt != _gxs_identity_widgets.end(); ++itExt) { + IdentityWidget *widget = itExt->second; + widget->setMinimumSize(QSize(100, 150)); + widget->setMaximumSize(QSize(100, 150)); + } + std::map::iterator itInt; + for (itInt = _pgp_identity_widgets.begin(); itInt != _pgp_identity_widgets.end(); ++itInt) { + IdentityWidget *widget = itInt->second; + widget->setMinimumSize(QSize(100, 150)); + widget->setMaximumSize(QSize(100, 150)); + } + } +} diff --git a/retroshare-gui/src/gui/People/PeopleDialog.h b/retroshare-gui/src/gui/People/PeopleDialog.h index 808c61a26..8aba50bf2 100644 --- a/retroshare-gui/src/gui/People/PeopleDialog.h +++ b/retroshare-gui/src/gui/People/PeopleDialog.h @@ -66,6 +66,11 @@ class PeopleDialog : public MainPage, public Ui::PeopleDialog, public TokenRespo private slots: void updateCirclesDisplay(bool); + void on_listViewButton_toggled(bool checked); + void on_thumbnailViewButton_toggled(bool checked); + void on_searchPeopleLineEdit_textChanged(const QString &text); + void on_sortPeopleComboBox_currentIndexChanged(int index); + void iw_AddButtonClickedExt(); void iw_AddButtonClickedInt(); void addToCircleExt(); @@ -94,6 +99,20 @@ private: void reloadAll(); void populatePictureFlowExt(); void populatePictureFlowInt(); + void filterIdentities(); + void sortIdentities(); + void setViewMode(int mode); + + enum ViewMode { + VIEW_MODE_LIST = 0, + VIEW_MODE_THUMBNAIL = 1 + }; + + int mCurrentViewMode; + QString mSearchFilter; + int mSortMethod; + + void setIdentitiesViewMode(int mode); TokenQueue *mIdentityQueue; TokenQueue *mCirclesQueue; diff --git a/retroshare-gui/src/gui/People/PeopleDialog.ui b/retroshare-gui/src/gui/People/PeopleDialog.ui index 416496a8a..2b7c06755 100644 --- a/retroshare-gui/src/gui/People/PeopleDialog.ui +++ b/retroshare-gui/src/gui/People/PeopleDialog.ui @@ -1,203 +1,294 @@ - - - PeopleDialog - - - - 0 - 0 - 727 - 524 - - - - - 0 - 0 - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - 0 - - - - - 0 - 0 - - - - People - - - - - - Qt::Vertical - - - - - 0 - 250 - - - - true - - - - - 0 - 0 - 701 - 248 - - - - - - - - - - - - 0 - 0 - - - - Drag your circles or people to each other. - - - Qt::AlignCenter - - - - - - - true - - - - - - - - - - - - - 0 - 0 - - - - Internal - - - - - - Qt::Vertical - - - - - 0 - 250 - - - - true - - - - - 0 - 0 - 701 - 248 - - - - - - - - - - - - 0 - 0 - - - - Drag your circles or people to each other. - - - Qt::AlignCenter - - - - - - - true - - - - - - - - - - - - - - - - PictureFlow - QWidget -
gui/common/PictureFlow.h
- 1 -
- - FlowLayoutWidget - QWidget -
gui/common/FlowLayout.h
- 1 -
-
- - - - -
+ + + PeopleDialog + + + + 0 + 0 + 727 + 524 + + + + + 0 + 0 + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + List + + + true + + + true + + + List View + + + + + + + Thumbnail + + + true + + + Thumbnail View + + + + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + + + Search people... + + + 200 + + + + + + + 150 + + + + Sort: Reputation + + + + + Sort: Recommended + + + + + Sort: Popularity + + + + + Sort: Name + + + + + + + + + + + true + + + 0 + + + + + 0 + 0 + + + + People + + + + + + Qt::Vertical + + + + + 0 + 250 + + + + true + + + + + 0 + 0 + 701 + 248 + + + + + + + + + + + + 0 + 0 + + + + Drag your circles or people to each other. + + + Qt::AlignCenter + + + + + + + true + + + + + + + + + + + + + 0 + 0 + + + + Internal + + + + + + Qt::Vertical + + + + + 0 + 250 + + + + true + + + + + 0 + 0 + 701 + 248 + + + + + + + + + + + + 0 + 0 + + + + Drag your circles or people to each other. + + + Qt::AlignCenter + + + + + + + true + + + + + + + + + + + + + + + + PictureFlow + QWidget +
gui/common/PictureFlow.h
+ 1 +
+ + FlowLayoutWidget + QWidget +
gui/common/FlowLayout.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/common/AvatarDefs.cpp b/retroshare-gui/src/gui/common/AvatarDefs.cpp index ac6017fa5..726b43280 100644 --- a/retroshare-gui/src/gui/common/AvatarDefs.cpp +++ b/retroshare-gui/src/gui/common/AvatarDefs.cpp @@ -19,6 +19,8 @@ *******************************************************************************/ #include +#include +#include #include #include @@ -28,6 +30,66 @@ #include "AvatarDefs.h" #include "gui/common/FilesDefs.h" +#define AVATAR_CACHE_DIR "avatars" + +QString AvatarDefs::getAvatarCacheDir() +{ + QString cacheDir = QDir::homePath() + "/.cache/RetroShare/"; + if (!QDir(cacheDir).exists()) { + QDir().mkpath(cacheDir); + } + return cacheDir + AVATAR_CACHE_DIR + "/"; +} + +bool AvatarDefs::loadAvatarFromDiskCache(const RsPeerId& sslId, QPixmap &avatar) +{ + QString cacheDir = getAvatarCacheDir(); + if (!QDir(cacheDir).exists()) { + QDir().mkpath(cacheDir); + } + + QString filePath = cacheDir + QString::fromStdString(sslId.toStdString()) + ".png"; + QFile file(filePath); + + if (file.exists()) { + if (avatar.load(filePath)) { + return true; + } + } + return false; +} + +bool AvatarDefs::saveAvatarToDiskCache(const RsPeerId& sslId, const QPixmap &avatar) +{ + QString cacheDir = getAvatarCacheDir(); + if (!QDir(cacheDir).exists()) { + QDir().mkpath(cacheDir); + } + + QString filePath = cacheDir + QString::fromStdString(sslId.toStdString()) + ".png"; + return avatar.save(filePath, "PNG"); +} + +void AvatarDefs::cleanupAvatarDiskCache() +{ + QString cacheDir = getAvatarCacheDir(); + QDir dir(cacheDir); + + if (!dir.exists()) { + return; + } + + // Remove avatars older than 30 days + QDateTime threshold = QDateTime::currentDateTime().addDays(-30); + QFileInfoList files = dir.entryInfoList(QStringList() << "*.png", QDir::Files); + + for (const QFileInfo &file : files) { + if (file.lastModified() < threshold) { + dir.remove(file.fileName()); + } + } +} + void AvatarDefs::getOwnAvatar(QPixmap &avatar, const QString& defaultImage) { unsigned char *data = NULL; @@ -46,12 +108,30 @@ void AvatarDefs::getOwnAvatar(QPixmap &avatar, const QString& defaultImage) free(data); } + bool AvatarDefs::getAvatarFromSslId(const RsPeerId& sslId, QPixmap &avatar, const QString& defaultImage) { unsigned char *data = NULL; int size = 0; - /* get avatar */ + // First try to load from disk cache + if (loadAvatarFromDiskCache(sslId, avatar)) { + // Got from cache, now check if network has newer version + rsChats->getAvatarData(RsPeerId(sslId), data, size); + if (size > 0) { + // Network has a newer avatar, update cache + QPixmap networkAvatar; + GxsIdDetails::loadPixmapFromData(data, size, networkAvatar, GxsIdDetails::LARGE); + saveAvatarToDiskCache(sslId, networkAvatar); + avatar = networkAvatar; + free(data); + return true; + } + // No network avatar, use cached one + return true; + } + + /* get avatar from network */ rsChats->getAvatarData(RsPeerId(sslId), data, size); if (size == 0) { if (!defaultImage.isEmpty()) { @@ -63,9 +143,13 @@ bool AvatarDefs::getAvatarFromSslId(const RsPeerId& sslId, QPixmap &avatar, cons /* load image */ GxsIdDetails::loadPixmapFromData(data, size, avatar, GxsIdDetails::LARGE) ; + // Save to disk cache for persistence + saveAvatarToDiskCache(sslId, avatar); + free(data); return true; } + bool AvatarDefs::getAvatarFromGxsId(const RsGxsId& gxsId, QPixmap &avatar, const QString& defaultImage) { //int size = 0; diff --git a/retroshare-gui/src/gui/common/AvatarDefs.h b/retroshare-gui/src/gui/common/AvatarDefs.h index a92104be1..2005a9bbd 100644 --- a/retroshare-gui/src/gui/common/AvatarDefs.h +++ b/retroshare-gui/src/gui/common/AvatarDefs.h @@ -39,7 +39,12 @@ public: static bool getAvatarFromSslId(const RsPeerId& sslId, QPixmap &avatar, const QString& defaultImage = AVATAR_DEFAULT_IMAGE); static bool getAvatarFromGpgId(const RsPgpId & gpgId, QPixmap &avatar, const QString& defaultImage = AVATAR_DEFAULT_IMAGE); static bool getAvatarFromGxsId(const RsGxsId & gxsId, QPixmap &avatar, const QString& defaultImage = AVATAR_DEFAULT_IMAGE); + + // Disk cache methods for persistent avatars + static QString getAvatarCacheDir(); + static bool loadAvatarFromDiskCache(const RsPeerId& sslId, QPixmap &avatar); + static bool saveAvatarToDiskCache(const RsPeerId& sslId, const QPixmap &avatar); + static void cleanupAvatarDiskCache(); }; #endif -