mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 12:38:48 +03:00
Implement Privacy Screen
* Add handles for window focus gained / focus lossed and connect to timer * Clean up some of the PrivacyScreen.qml code * Connect settings to PrivacyScreen visibility
This commit is contained in:
parent
cb93ac3402
commit
bfeb766a91
8 changed files with 137 additions and 35 deletions
|
@ -22,6 +22,8 @@ if [ ! -z "$QMLFORMAT_PATH" ]; then
|
||||||
do
|
do
|
||||||
qmlformat -i "$f"
|
qmlformat -i "$f"
|
||||||
done;
|
done;
|
||||||
|
else
|
||||||
|
echo "qmlformat not found; skipping qml formatting"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
git diff --exit-code
|
git diff --exit-code
|
||||||
|
|
|
@ -1,13 +1,28 @@
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
|
import im.nheko 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: privacyScreen
|
||||||
|
|
||||||
property var timelineRoot
|
property var timelineRoot
|
||||||
property var imageSource
|
property var imageSource: ""
|
||||||
property int screenTimeout
|
property int screenTimeout
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: TimelineManager
|
||||||
|
onFocusChanged: {
|
||||||
|
if (TimelineManager.isWindowFocused) {
|
||||||
|
screenSaverTimer.stop();
|
||||||
|
screenSaver.state = "Invisible";
|
||||||
|
} else {
|
||||||
|
screenSaverTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: screenSaverTimer
|
id: screenSaverTimer
|
||||||
|
|
||||||
|
@ -15,36 +30,98 @@ Item {
|
||||||
running: true
|
running: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
timelineRoot.grabToImage(function(result) {
|
timelineRoot.grabToImage(function(result) {
|
||||||
|
screenSaver.state = "Visible";
|
||||||
imageSource = result.url;
|
imageSource = result.url;
|
||||||
screenSaver.visible = true;
|
|
||||||
particles.resume();
|
|
||||||
}, Qt.size(width, height));
|
}, Qt.size(width, height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset screensaver timer when clicks are received
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
// Pass mouse events through
|
|
||||||
propagateComposedEvents: true
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
screenSaverTimer.restart();
|
|
||||||
mouse.accepted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: screenSaver
|
id: screenSaver
|
||||||
|
|
||||||
|
state: "Invisible"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: false
|
visible: false
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "Visible"
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: screenSaver
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: screenSaver
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "Invisible"
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: screenSaver
|
||||||
|
opacity: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: screenSaver
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
transitions: [
|
||||||
|
Transition {
|
||||||
|
from: "Visible"
|
||||||
|
to: "Invisible"
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
NumberAnimation {
|
||||||
|
target: screenSaver
|
||||||
|
property: "opacity"
|
||||||
|
duration: 250
|
||||||
|
easing.type: Easing.InQuad
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: screenSaver
|
||||||
|
property: "visible"
|
||||||
|
duration: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
from: "Invisible"
|
||||||
|
to: "Visible"
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
NumberAnimation {
|
||||||
|
target: screenSaver
|
||||||
|
property: "visible"
|
||||||
|
duration: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: screenSaver
|
||||||
|
property: "opacity"
|
||||||
|
duration: 500
|
||||||
|
easing.type: Easing.InQuad
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: image
|
id: image
|
||||||
|
|
||||||
visible: screenSaver.visible
|
cache: false
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: imageSource
|
source: imageSource
|
||||||
}
|
}
|
||||||
|
@ -65,17 +142,6 @@ Item {
|
||||||
radius: 50
|
radius: 50
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
propagateComposedEvents: true
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
screenSaver.visible = false;
|
|
||||||
screenSaverTimer.restart();
|
|
||||||
mouse.accepted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,6 +312,8 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
|
||||||
&ChatPage::initializeMentions,
|
&ChatPage::initializeMentions,
|
||||||
user_mentions_popup_,
|
user_mentions_popup_,
|
||||||
&popups::UserMentions::initializeMentions);
|
&popups::UserMentions::initializeMentions);
|
||||||
|
connect(
|
||||||
|
this, &ChatPage::chatFocusChanged, view_manager_, &TimelineViewManager::chatFocusChanged);
|
||||||
connect(this, &ChatPage::syncUI, this, [this](const mtx::responses::Rooms &rooms) {
|
connect(this, &ChatPage::syncUI, this, [this](const mtx::responses::Rooms &rooms) {
|
||||||
try {
|
try {
|
||||||
room_list_->cleanupInvites(cache::invites());
|
room_list_->cleanupInvites(cache::invites());
|
||||||
|
|
|
@ -127,7 +127,6 @@ public slots:
|
||||||
void receivedSessionKey(const std::string &room_id, const std::string &session_id);
|
void receivedSessionKey(const std::string &room_id, const std::string &session_id);
|
||||||
void decryptDownloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescription keyDesc,
|
void decryptDownloadedSecrets(mtx::secret_storage::AesHmacSha2KeyDescription keyDesc,
|
||||||
const SecretsToDecrypt &secrets);
|
const SecretsToDecrypt &secrets);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectionLost();
|
void connectionLost();
|
||||||
void connectionRestored();
|
void connectionRestored();
|
||||||
|
@ -176,6 +175,7 @@ signals:
|
||||||
void retrievedPresence(const QString &statusMsg, mtx::presence::PresenceState state);
|
void retrievedPresence(const QString &statusMsg, mtx::presence::PresenceState state);
|
||||||
void themeChanged();
|
void themeChanged();
|
||||||
void decryptSidebarChanged();
|
void decryptSidebarChanged();
|
||||||
|
void chatFocusChanged(const bool focused);
|
||||||
|
|
||||||
//! Signals for device verificaiton
|
//! Signals for device verificaiton
|
||||||
void receivedDeviceVerificationAccept(
|
void receivedDeviceVerificationAccept(
|
||||||
|
|
|
@ -130,6 +130,9 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
|
SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
|
||||||
|
|
||||||
connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar()));
|
connect(chat_page_, SIGNAL(contentLoaded()), this, SLOT(removeOverlayProgressBar()));
|
||||||
|
|
||||||
|
connect(this, &MainWindow::focusChanged, chat_page_, &ChatPage::chatFocusChanged);
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
chat_page_, &ChatPage::showUserSettingsPage, this, &MainWindow::showUserSettingsPage);
|
chat_page_, &ChatPage::showUserSettingsPage, this, &MainWindow::showUserSettingsPage);
|
||||||
|
|
||||||
|
@ -204,6 +207,19 @@ MainWindow::resizeEvent(QResizeEvent *event)
|
||||||
QMainWindow::resizeEvent(event);
|
QMainWindow::resizeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MainWindow::event(QEvent *event)
|
||||||
|
{
|
||||||
|
auto type = event->type();
|
||||||
|
if (type == QEvent::WindowActivate) {
|
||||||
|
emit focusChanged(true);
|
||||||
|
} else if (type == QEvent::WindowDeactivate) {
|
||||||
|
emit focusChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QMainWindow::event(event);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MainWindow::adjustSideBars()
|
MainWindow::adjustSideBars()
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,6 +88,7 @@ protected:
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
|
bool event(QEvent *event) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
//! Show or hide the sidebars based on window's size.
|
//! Show or hide the sidebars based on window's size.
|
||||||
|
@ -115,6 +116,9 @@ private slots:
|
||||||
|
|
||||||
virtual void setWindowTitle(int notificationCount);
|
virtual void setWindowTitle(int notificationCount);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void focusChanged(const bool focused);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool loadJdenticonPlugin();
|
bool loadJdenticonPlugin();
|
||||||
|
|
||||||
|
|
|
@ -836,13 +836,15 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
||||||
decryptSidebar_,
|
decryptSidebar_,
|
||||||
tr("Decrypt the messages shown in the sidebar.\nOnly affects messages in "
|
tr("Decrypt the messages shown in the sidebar.\nOnly affects messages in "
|
||||||
"encrypted chats."));
|
"encrypted chats."));
|
||||||
boxWrap(tr("Encrypted chat privacy screen"),
|
boxWrap(tr("Privacy Screen"),
|
||||||
privacyScreen_,
|
privacyScreen_,
|
||||||
tr("When the window loses focus, the timeline will\nbe blurred."));
|
tr("When the window loses focus, the timeline will\nbe blurred."));
|
||||||
boxWrap(tr("Privacy screen timeout"),
|
boxWrap(
|
||||||
privacyScreenTimeout_,
|
tr("Privacy screen timeout"),
|
||||||
tr("Set timeout for how long after window loses\nfocus before the screen"
|
privacyScreenTimeout_,
|
||||||
" will be blurred.\nSet to 0 to blur immediately after focus loss."));
|
tr("Set timeout (in seconds) for how long after window loses\nfocus before the screen"
|
||||||
|
" will be blurred.\nSet to 0 to blur immediately after focus loss. Max value of 1 "
|
||||||
|
"hour (3600 seconds)"));
|
||||||
boxWrap(tr("Show buttons in timeline"),
|
boxWrap(tr("Show buttons in timeline"),
|
||||||
timelineButtonsToggle_,
|
timelineButtonsToggle_,
|
||||||
tr("Show buttons to quickly reply, react or access additional options next to each "
|
tr("Show buttons to quickly reply, react or access additional options next to each "
|
||||||
|
|
|
@ -36,6 +36,8 @@ class TimelineViewManager : public QObject
|
||||||
bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
|
bool isInitialSync MEMBER isInitialSync_ READ isInitialSync NOTIFY initialSyncChanged)
|
||||||
Q_PROPERTY(
|
Q_PROPERTY(
|
||||||
bool isNarrowView MEMBER isNarrowView_ READ isNarrowView NOTIFY narrowViewChanged)
|
bool isNarrowView MEMBER isNarrowView_ READ isNarrowView NOTIFY narrowViewChanged)
|
||||||
|
Q_PROPERTY(
|
||||||
|
bool isWindowFocused MEMBER isWindowFocused_ READ isWindowFocused NOTIFY focusChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr);
|
TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr);
|
||||||
|
@ -54,6 +56,7 @@ public:
|
||||||
Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; }
|
Q_INVOKABLE TimelineModel *activeTimeline() const { return timeline_; }
|
||||||
Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; }
|
Q_INVOKABLE bool isInitialSync() const { return isInitialSync_; }
|
||||||
bool isNarrowView() const { return isNarrowView_; }
|
bool isNarrowView() const { return isNarrowView_; }
|
||||||
|
bool isWindowFocused() const { return isWindowFocused_; }
|
||||||
Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const;
|
Q_INVOKABLE void openImageOverlay(QString mxcUrl, QString eventId) const;
|
||||||
Q_INVOKABLE QColor userColor(QString id, QColor background);
|
Q_INVOKABLE QColor userColor(QString id, QColor background);
|
||||||
Q_INVOKABLE QString escapeEmoji(QString str) const;
|
Q_INVOKABLE QString escapeEmoji(QString str) const;
|
||||||
|
@ -83,11 +86,17 @@ signals:
|
||||||
void inviteUsers(QStringList users);
|
void inviteUsers(QStringList users);
|
||||||
void showRoomList();
|
void showRoomList();
|
||||||
void narrowViewChanged();
|
void narrowViewChanged();
|
||||||
|
void focusChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
|
void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
|
||||||
void receivedSessionKey(const std::string &room_id, const std::string &session_id);
|
void receivedSessionKey(const std::string &room_id, const std::string &session_id);
|
||||||
void initWithMessages(const std::vector<QString> &roomIds);
|
void initWithMessages(const std::vector<QString> &roomIds);
|
||||||
|
void chatFocusChanged(bool focused)
|
||||||
|
{
|
||||||
|
isWindowFocused_ = focused;
|
||||||
|
emit focusChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void setHistoryView(const QString &room_id);
|
void setHistoryView(const QString &room_id);
|
||||||
TimelineModel *getHistoryView(const QString &room_id)
|
TimelineModel *getHistoryView(const QString &room_id)
|
||||||
|
@ -145,8 +154,9 @@ private:
|
||||||
TimelineModel *timeline_ = nullptr;
|
TimelineModel *timeline_ = nullptr;
|
||||||
CallManager *callManager_ = nullptr;
|
CallManager *callManager_ = nullptr;
|
||||||
|
|
||||||
bool isInitialSync_ = true;
|
bool isInitialSync_ = true;
|
||||||
bool isNarrowView_ = false;
|
bool isNarrowView_ = false;
|
||||||
|
bool isWindowFocused_ = false;
|
||||||
|
|
||||||
QHash<QString, QColor> userColors;
|
QHash<QString, QColor> userColors;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue