mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Add ability to pin Usercards to stay open even if it loses focus (#3884)
Co-authored-by: pajlada <rasmus.karlsson@pajlada.com> Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com> Co-authored-by: James Upjohn <jammehcow@jammehcow.co.nz>
This commit is contained in:
parent
070151fbc8
commit
06b28ea0ab
|
@ -6,6 +6,7 @@
|
|||
- Major: Added multi-channel searching to search dialog via keyboard shortcut. (Ctrl+Shift+F by default) (#3694, #3875)
|
||||
- Major: Added support for emotes and badges from [7TV](https://7tv.app). [Wiki Page](https://wiki.chatterino.com/Third_party_services/#7tv) (#4002, #4062)
|
||||
- Major: Added support for Right-to-Left Languages (#3958, #4139)
|
||||
- Minor: Added ability to pin Usercards to stay open even if it loses focus. Only available if "Automatically close usercard when it loses focus" is enabled. (#3884)
|
||||
- Minor: Allow hiding moderation actions in streamer mode. (#3926)
|
||||
- Minor: Added highlights for `Elevated Messages`. (#4016)
|
||||
- Minor: Removed total views from the usercard, as Twitch no longer updates the number. (#3792)
|
||||
|
|
BIN
resources/buttons/pinDisabledDark.png
Normal file
BIN
resources/buttons/pinDisabledDark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 996 B |
23
resources/buttons/pinDisabledDark.svg
Normal file
23
resources/buttons/pinDisabledDark.svg
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="15.999924mm"
|
||||
height="15.999949mm"
|
||||
viewBox="0 0 15.999924 15.999949"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs2" /><g
|
||||
id="layer2"
|
||||
transform="translate(-4.439446e-5,3.0446178e-5)"><path
|
||||
class="UnoptimicedTransforms"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 12.435417,-0.52916667 3.96875,3.96874997 V 3.96875 l -4.7625,4.7625 V 11.1125 L 11.1125,11.641667 H 10.847917 L 4.2333333,5.0270833 V 4.7625 L 4.7625,4.2333333 h 2.38125 l 4.7625,-4.76249997 z"
|
||||
id="path234"
|
||||
transform="matrix(1.0300653,0,0,1.0300668,-1.0336639,0.68131565)" /><path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.272538px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 5.098444,9.8113564 6.1885966,10.901511 1.2829102,15.807204 0.19275776,14.717051 Z"
|
||||
id="path1157" /></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/buttons/pinDisabledLight.png
Normal file
BIN
resources/buttons/pinDisabledLight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 989 B |
23
resources/buttons/pinDisabledLight.svg
Normal file
23
resources/buttons/pinDisabledLight.svg
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="15.999924mm"
|
||||
height="15.999949mm"
|
||||
viewBox="0 0 15.999924 15.999949"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs2" /><g
|
||||
id="layer2"
|
||||
transform="translate(-4.439446e-5,3.0446178e-5)"><path
|
||||
class="UnoptimicedTransforms"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 12.435417,-0.52916667 3.96875,3.96874997 V 3.96875 l -4.7625,4.7625 V 11.1125 L 11.1125,11.641667 H 10.847917 L 4.2333333,5.0270833 V 4.7625 L 4.7625,4.2333333 h 2.38125 l 4.7625,-4.76249997 z"
|
||||
id="path234"
|
||||
transform="matrix(1.0300653,0,0,1.0300668,-1.0336639,0.68131565)" /><path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.272538px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 5.098444,9.8113564 6.1885966,10.901511 1.2829102,15.807204 0.19275776,14.717051 Z"
|
||||
id="path1157" /></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/buttons/pinEnabled.png
Normal file
BIN
resources/buttons/pinEnabled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
23
resources/buttons/pinEnabled.svg
Normal file
23
resources/buttons/pinEnabled.svg
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="15.999924mm"
|
||||
height="15.999949mm"
|
||||
viewBox="0 0 15.999924 15.999949"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs2" /><g
|
||||
id="layer2"
|
||||
transform="translate(-4.439446e-5,3.0446178e-5)"><path
|
||||
class="UnoptimicedTransforms"
|
||||
style="fill:#e25c41;fill-opacity:1;stroke:#e25c41;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 12.435417,-0.52916667 3.96875,3.96874997 V 3.96875 l -4.7625,4.7625 V 11.1125 L 11.1125,11.641667 H 10.847917 L 4.2333333,5.0270833 V 4.7625 L 4.7625,4.2333333 h 2.38125 l 4.7625,-4.76249997 z"
|
||||
id="path234"
|
||||
transform="matrix(1.0300653,0,0,1.0300668,-1.0336639,0.68131565)" /><path
|
||||
style="fill:#e25c41;fill-opacity:1;stroke:#e25c41;stroke-width:0.272538px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 5.098444,9.8113564 6.1885966,10.901511 1.2829102,15.807204 0.19275776,14.717051 Z"
|
||||
id="path1157" /></g></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -38,6 +38,12 @@
|
|||
<file>buttons/modModeDisabled2.png</file>
|
||||
<file>buttons/modModeEnabled.png</file>
|
||||
<file>buttons/modModeEnabled2.png</file>
|
||||
<file>buttons/pinDisabledDark.png</file>
|
||||
<file>buttons/pinDisabledDark.svg</file>
|
||||
<file>buttons/pinDisabledLight.png</file>
|
||||
<file>buttons/pinDisabledLight.svg</file>
|
||||
<file>buttons/pinEnabled.png</file>
|
||||
<file>buttons/pinEnabled.svg</file>
|
||||
<file>buttons/replyDark.png</file>
|
||||
<file>buttons/replyDark.svg</file>
|
||||
<file>buttons/replyThreadDark.png</file>
|
||||
|
|
|
@ -34,6 +34,9 @@ Resources2::Resources2()
|
|||
this->buttons.modModeDisabled2 = QPixmap(":/buttons/modModeDisabled2.png");
|
||||
this->buttons.modModeEnabled = QPixmap(":/buttons/modModeEnabled.png");
|
||||
this->buttons.modModeEnabled2 = QPixmap(":/buttons/modModeEnabled2.png");
|
||||
this->buttons.pinDisabledDark = QPixmap(":/buttons/pinDisabledDark.png");
|
||||
this->buttons.pinDisabledLight = QPixmap(":/buttons/pinDisabledLight.png");
|
||||
this->buttons.pinEnabled = QPixmap(":/buttons/pinEnabled.png");
|
||||
this->buttons.replyDark = QPixmap(":/buttons/replyDark.png");
|
||||
this->buttons.replyThreadDark = QPixmap(":/buttons/replyThreadDark.png");
|
||||
this->buttons.search = QPixmap(":/buttons/search.png");
|
||||
|
|
|
@ -41,6 +41,9 @@ public:
|
|||
QPixmap modModeDisabled2;
|
||||
QPixmap modModeEnabled;
|
||||
QPixmap modModeEnabled2;
|
||||
QPixmap pinDisabledDark;
|
||||
QPixmap pinDisabledLight;
|
||||
QPixmap pinEnabled;
|
||||
QPixmap replyDark;
|
||||
QPixmap replyThreadDark;
|
||||
QPixmap search;
|
||||
|
|
|
@ -278,10 +278,12 @@ void Theme::actuallyUpdate(double hue, double multiplier)
|
|||
if (this->isLightTheme())
|
||||
{
|
||||
this->buttons.copy = getResources().buttons.copyDark;
|
||||
this->buttons.pin = getResources().buttons.pinDisabledDark;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->buttons.copy = getResources().buttons.copyLight;
|
||||
this->buttons.pin = getResources().buttons.pinDisabledLight;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ public:
|
|||
|
||||
struct {
|
||||
QPixmap copy;
|
||||
QPixmap pin;
|
||||
} buttons;
|
||||
|
||||
void normalizeColor(QColor &color);
|
||||
|
|
|
@ -134,11 +134,13 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent,
|
|||
Split *split)
|
||||
: DraggablePopup(closeAutomatically, parent)
|
||||
, split_(split)
|
||||
, closeAutomatically_(closeAutomatically)
|
||||
{
|
||||
assert(split != nullptr &&
|
||||
"split being nullptr causes lots of bugs down the road");
|
||||
this->setWindowTitle("Usercard");
|
||||
this->setStayInScreenRect(true);
|
||||
this->updateFocusLoss();
|
||||
|
||||
HotkeyController::HotkeyMap actions{
|
||||
{"delete",
|
||||
|
@ -349,6 +351,22 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent,
|
|||
|
||||
this->ui_.localizedNameLabel->setVisible(false);
|
||||
this->ui_.localizedNameCopyButton->setVisible(false);
|
||||
|
||||
// button to pin the window (only if we close automatically)
|
||||
if (this->closeAutomatically_)
|
||||
{
|
||||
this->ui_.pinButton = box.emplace<Button>().getElement();
|
||||
this->ui_.pinButton->setPixmap(
|
||||
getApp()->themes->buttons.pin);
|
||||
this->ui_.pinButton->setScaleIndependantSize(18, 18);
|
||||
this->ui_.pinButton->setToolTip("Pin Window");
|
||||
QObject::connect(this->ui_.pinButton, &Button::leftClicked,
|
||||
[this]() {
|
||||
this->closeAutomatically_ =
|
||||
!this->closeAutomatically_;
|
||||
this->updateFocusLoss();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// items on the left
|
||||
|
@ -873,6 +891,26 @@ void UserInfoPopup::updateUserData()
|
|||
this->ui_.ignoreHighlights->setEnabled(false);
|
||||
}
|
||||
|
||||
void UserInfoPopup::updateFocusLoss()
|
||||
{
|
||||
if (this->closeAutomatically_)
|
||||
{
|
||||
this->setActionOnFocusLoss(BaseWindow::Delete);
|
||||
if (this->ui_.pinButton != nullptr)
|
||||
{
|
||||
this->ui_.pinButton->setPixmap(getApp()->themes->buttons.pin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setActionOnFocusLoss(BaseWindow::Nothing);
|
||||
if (this->ui_.pinButton != nullptr)
|
||||
{
|
||||
this->ui_.pinButton->setPixmap(getResources().buttons.pinEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UserInfoPopup::loadAvatar(const QUrl &url)
|
||||
{
|
||||
QNetworkRequest req(url);
|
||||
|
|
|
@ -36,6 +36,7 @@ private:
|
|||
void installEvents();
|
||||
void updateUserData();
|
||||
void updateLatestMessages();
|
||||
void updateFocusLoss();
|
||||
|
||||
void loadAvatar(const QUrl &url);
|
||||
bool isMod_;
|
||||
|
@ -46,8 +47,10 @@ private:
|
|||
QString userName_;
|
||||
QString userId_;
|
||||
QString avatarUrl_;
|
||||
|
||||
// The channel the popup was opened from (e.g. /mentions or #forsen). Can be a special channel.
|
||||
ChannelPtr channel_;
|
||||
|
||||
// The channel the messages are rendered from (e.g. #forsen). Can be a special channel, but will try to not be where possible.
|
||||
ChannelPtr underlyingChannel_;
|
||||
|
||||
|
@ -55,6 +58,11 @@ private:
|
|||
|
||||
std::unique_ptr<pajlada::Signals::ScopedConnection> refreshConnection_;
|
||||
|
||||
// If we should close the dialog automatically if the user clicks out
|
||||
// Initially set based on the "Automatically close usercard when it loses focus" setting
|
||||
// If that setting is enabled, this can be toggled on and off using the pin in the top-right corner
|
||||
bool closeAutomatically_;
|
||||
|
||||
struct {
|
||||
Button *avatarButton = nullptr;
|
||||
Button *localizedNameCopyButton = nullptr;
|
||||
|
@ -64,6 +72,8 @@ private:
|
|||
Label *followerCountLabel = nullptr;
|
||||
Label *createdDateLabel = nullptr;
|
||||
Label *userIDLabel = nullptr;
|
||||
// Can be uninitialized if usercard is not configured to close on focus loss
|
||||
Button *pinButton = nullptr;
|
||||
Label *followageLabel = nullptr;
|
||||
Label *subageLabel = nullptr;
|
||||
|
||||
|
|
|
@ -700,7 +700,7 @@ void GeneralPage::initLayout(GeneralPageView &layout)
|
|||
s.mentionUsersWithComma);
|
||||
layout.addCheckbox("Show joined users (< 1000 chatters)", s.showJoins);
|
||||
layout.addCheckbox("Show parted users (< 1000 chatters)", s.showParts);
|
||||
layout.addCheckbox("Automatically close user popup when it loses focus",
|
||||
layout.addCheckbox("Automatically close usercard when it loses focus",
|
||||
s.autoCloseUserPopup);
|
||||
layout.addCheckbox(
|
||||
"Automatically close reply thread popup when it loses focus",
|
||||
|
|
Loading…
Reference in a new issue