mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Merge branch 'master' of github.com:Chatterino/chatterino2
This commit is contained in:
commit
0dd6934f02
42 changed files with 394 additions and 100 deletions
48
.github/workflows/build.yml
vendored
48
.github/workflows/build.yml
vendored
|
@ -63,29 +63,32 @@ jobs:
|
|||
version: ${{ matrix.qt-version }}
|
||||
|
||||
# WINDOWS
|
||||
|
||||
- name: Cache conan packages
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
uses: actions/cache@v2.1.4
|
||||
with:
|
||||
key: ${{ runner.os }}-conan-${{ hashFiles('**/conanfile.txt') }}-20210307
|
||||
key: ${{ runner.os }}-conan-${{ hashFiles('**/conanfile.txt') }}-20210412
|
||||
path: C:/.conan/
|
||||
|
||||
- name: Add Conan to path
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
run: echo "C:\Program Files\Conan\conan\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: Install dependencies (Windows)
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
run: |
|
||||
choco install conan -y
|
||||
|
||||
refreshenv
|
||||
shell: cmd
|
||||
|
||||
- name: Enable Developer Command Prompt
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
uses: ilammy/msvc-dev-cmd@v1.7.0
|
||||
|
||||
- name: Build (Windows)
|
||||
if: startsWith(matrix.os, 'windows') && matrix.build-system == 'qmake'
|
||||
run: |
|
||||
call "%programfiles(x86)%\Microsoft Visual Studio\%vs_version%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
mkdir build
|
||||
cd build
|
||||
"C:\Program Files\Conan\conan\conan.exe" install ..
|
||||
conan install ..
|
||||
qmake ..
|
||||
set cl=/MP
|
||||
nmake /S /NOLOGO
|
||||
|
@ -93,15 +96,13 @@ jobs:
|
|||
cp release/chatterino.exe Chatterino2/
|
||||
echo nightly > Chatterino2/modes
|
||||
7z a chatterino-windows-x86-64.zip Chatterino2/
|
||||
shell: cmd
|
||||
|
||||
|
||||
- name: Build with CMake (Windows)
|
||||
if: startsWith(matrix.os, 'windows') && matrix.build-system == 'cmake'
|
||||
run: |
|
||||
call "%programfiles(x86)%\Microsoft Visual Studio\%vs_version%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
mkdir build
|
||||
cd build
|
||||
"C:\Program Files\Conan\conan\conan.exe" install ..
|
||||
conan install ..
|
||||
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DUSE_CONAN=ON ..
|
||||
set cl=/MP
|
||||
nmake /S /NOLOGO
|
||||
|
@ -109,17 +110,10 @@ jobs:
|
|||
cp bin/chatterino.exe Chatterino2/
|
||||
echo nightly > Chatterino2/modes
|
||||
7z a chatterino-windows-x86-64.zip Chatterino2/
|
||||
shell: cmd
|
||||
|
||||
- name: Ensure build succeeded (Windows)
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
run: |
|
||||
cd build
|
||||
ls Chatterino2/chatterino.exe
|
||||
|
||||
- name: Upload artifact (Windows)
|
||||
if: startsWith(matrix.os, 'windows')
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
uses: actions/upload-artifact@v2.2.3
|
||||
with:
|
||||
name: chatterino-windows-x86-64-${{ matrix.qt-version }}-${{ matrix.build-system }}.zip
|
||||
path: build/chatterino-windows-x86-64.zip
|
||||
|
@ -176,7 +170,7 @@ jobs:
|
|||
|
||||
- name: Upload artifact (Ubuntu)
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
uses: actions/upload-artifact@v2.2.3
|
||||
with:
|
||||
name: Chatterino-x86_64-${{ matrix.qt-version }}-${{ matrix.build-system }}.AppImage
|
||||
path: build/Chatterino-x86_64.AppImage
|
||||
|
@ -221,7 +215,7 @@ jobs:
|
|||
|
||||
- name: Upload artifact (MacOS)
|
||||
if: startsWith(matrix.os, 'macos')
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
uses: actions/upload-artifact@v2.2.3
|
||||
with:
|
||||
name: chatterino-osx-${{ matrix.qt-version }}-${{ matrix.build-system }}.dmg
|
||||
path: build/chatterino-osx.dmg
|
||||
|
@ -245,32 +239,32 @@ jobs:
|
|||
Nightly Build
|
||||
prerelease: true
|
||||
|
||||
- uses: actions/download-artifact@v2.0.8
|
||||
- uses: actions/download-artifact@v2.0.9
|
||||
with:
|
||||
name: chatterino-windows-x86-64-5.15.2-qmake.zip
|
||||
path: windows/
|
||||
|
||||
- uses: actions/download-artifact@v2.0.8
|
||||
- uses: actions/download-artifact@v2.0.9
|
||||
with:
|
||||
name: chatterino-windows-x86-64-5.15.2-cmake.zip
|
||||
path: windows-cmake/
|
||||
|
||||
- uses: actions/download-artifact@v2.0.8
|
||||
- uses: actions/download-artifact@v2.0.9
|
||||
with:
|
||||
name: Chatterino-x86_64-5.15.2-qmake.AppImage
|
||||
path: linux/
|
||||
|
||||
- uses: actions/download-artifact@v2.0.8
|
||||
- uses: actions/download-artifact@v2.0.9
|
||||
with:
|
||||
name: Chatterino-x86_64-5.15.2-cmake.AppImage
|
||||
path: linux-cmake/
|
||||
|
||||
- uses: actions/download-artifact@v2.0.8
|
||||
- uses: actions/download-artifact@v2.0.9
|
||||
with:
|
||||
name: chatterino-osx-5.15.2-qmake.dmg
|
||||
path: macos/
|
||||
|
||||
- uses: actions/download-artifact@v2.0.8
|
||||
- uses: actions/download-artifact@v2.0.9
|
||||
with:
|
||||
name: chatterino-osx-5.15.2-cmake.dmg
|
||||
path: macos-cmake/
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -25,3 +25,6 @@
|
|||
[submodule "lib/websocketpp"]
|
||||
path = lib/websocketpp
|
||||
url = https://github.com/ziocleto/websocketpp
|
||||
[submodule "cmake/sanitizers-cmake"]
|
||||
path = cmake/sanitizers-cmake
|
||||
url = https://github.com/arsenm/sanitizers-cmake
|
||||
|
|
|
@ -6,8 +6,25 @@ Note on Qt version compatibility: If you are installing Qt from a package manage
|
|||
|
||||
_most likely works the same for other Debian-like distros_
|
||||
|
||||
1. Install dependencies (and the C++ IDE Qt Creator) `sudo apt install qtcreator qtmultimedia5-dev libqt5svg5-dev libboost-dev libssl-dev libboost-system-dev libboost-filesystem-dev cmake`
|
||||
1. Open `chatterino.pro` with QT Creator and build
|
||||
1. Install dependencies `sudo apt install qttools5-dev qtmultimedia5-dev libqt5svg5-dev libboost-dev libssl-dev libboost-system-dev libboost-filesystem-dev cmake g++`
|
||||
|
||||
### Through Qt Creator
|
||||
|
||||
1. Install C++ IDE Qt Creator `sudo apt install qtcreator`
|
||||
1. Open `chatterino.pro` with Qt Creator and select build
|
||||
|
||||
### Manually
|
||||
|
||||
1. go into project directory
|
||||
1. create build folder `mkdir build && cd build`
|
||||
|
||||
#### Using QMake
|
||||
|
||||
1. `qmake .. && make`
|
||||
|
||||
#### Using CMake
|
||||
|
||||
1. `cmake .. && make`
|
||||
|
||||
## Arch Linux
|
||||
|
||||
|
@ -17,15 +34,15 @@ _most likely works the same for other Debian-like distros_
|
|||
|
||||
### Manually
|
||||
|
||||
1. `sudo pacman -S qt5-base qt5-multimedia qt5-svg gst-plugins-ugly gst-plugins-good boost rapidjson pkgconf openssl cmake`
|
||||
1. `sudo pacman -S qt5-base qt5-multimedia qt5-svg qt5-tools gst-plugins-ugly gst-plugins-good boost rapidjson pkgconf openssl cmake`
|
||||
1. go into project directory
|
||||
1. create build folder `mkdir build && cd build`
|
||||
|
||||
### Using QMake
|
||||
#### Using QMake
|
||||
|
||||
1. `qmake .. && make`
|
||||
|
||||
### Using CMake
|
||||
#### Using CMake
|
||||
|
||||
1. `cmake .. && make`
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ Note: This installation will take about 1.5 GB of disk space.
|
|||
|
||||
### For our websocket library, we need OpenSSL 1.1
|
||||
|
||||
1. Download OpenSSL for windows, version `1.1.1i`: **[Download](https://slproweb.com/download/Win64OpenSSL-1_1_1i.exe)**
|
||||
1. Download OpenSSL for windows, version `1.1.1j`: **[Download](https://slproweb.com/download/Win64OpenSSL-1_1_1j.exe)**
|
||||
2. When prompted, install OpenSSL to `C:\local\openssl`
|
||||
3. When prompted, copy the OpenSSL DLLs to "The OpenSSL binaries (/bin) directory".
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
- Major: Added clip creation support. You can create clips with `/clip` command, `Alt+X` keybind or `Create a clip` option in split header's context menu. This requires a new authentication scope so re-authentication will be required to use it. (#2271, #2377, #2528)
|
||||
- Major: Added "Channel Filters". See https://wiki.chatterino.com/Filters/ for how they work or how to configure them. (#1748, #2083, #2090, #2200, #2225)
|
||||
- Major: Added Streamer Mode configuration (under `Settings -> General`), where you can select which features of Chatterino should behave differently when you are in Streamer Mode. (#2001, #2316, #2342, #2376)
|
||||
- Major: Color mentions to match the mentioned users. You can disable this by unchecking "Color @usernames" under `Settings -> General -> Advanced (misc.)`. (#1963, #2284)
|
||||
- Major: Add `/settitle` and `/setgame` commands, originally made for Mm2PL/Dankerino. (#2534, #2609)
|
||||
- Major: Color mentions to match the mentioned users. You can disable this by unchecking "Color @usernames" under `Settings -> General -> Advanced (misc.)`. (#1963, #2284, #2597)
|
||||
- Major: Commands `/ignore` and `/unignore` have been renamed to `/block` and `/unblock` in order to keep consistency with Twitch's terms. (#2370)
|
||||
- Major: Added support for bit emotes - the ones you unlock after cheering to streamer. (#2550)
|
||||
- Minor: Added `/clearmessages` command - does what "Burger menu -> More -> Clear messages" does. (#2485)
|
||||
|
@ -43,7 +44,7 @@
|
|||
- Minor: Show channels live now enabled by default
|
||||
- Minor: Bold usernames enabled by default
|
||||
- Minor: Improve UX of the "Login expired!" message (#2029)
|
||||
- Minor: PageUp and PageDown now scroll in the selected split (#2070, #2081)
|
||||
- Minor: PageUp and PageDown now scroll in the selected split and in the emote popup (#2070, #2081, #2410, #2607)
|
||||
- Minor: Allow highlights to be excluded from `/mentions`. Excluded highlights will not trigger tab highlights either. (#1793, #2036)
|
||||
- Minor: Flag all popup dialogs as actual dialogs so they get the relevant window manager hints (#1843, #2182, #2185, #2232, #2234)
|
||||
- Minor: Don't show update button for nightly builds on macOS and Linux, this was already the case for Windows (#2163, #2164)
|
||||
|
@ -59,6 +60,7 @@
|
|||
- Minor: Added `/streamlink` command. Usage: `/streamlink <channel>`. You can also use the command without arguments in any twitch channel to open it in streamlink. (#2443, #2495)
|
||||
- Minor: Humanized all numbers visible to end-users. (#2488)
|
||||
- Minor: Added a context menu to avatar in usercard. It opens on right-clicking the avatar in usercard. (#2517)
|
||||
- Minor: Handle messages that users can share after unlocking a new bits badge. (#2611)
|
||||
- Bugfix: Fix crash occurring when pressing Escape in the Color Picker Dialog (#1843)
|
||||
- Bugfix: Fix bug where the "check user follow state" event could trigger a network request requesting the user to follow or unfollow a user. By itself its quite harmless as it just repeats to Twitch the same follow state we had, so no follows should have been lost by this but it meant there was a rogue network request that was fired that could cause a crash (#1906)
|
||||
- Bugfix: /usercard command will now respect the "Automatically close user popup" setting (#1918)
|
||||
|
@ -81,11 +83,14 @@
|
|||
- Bugfix: Fix anonymous users being pinged by "username" justinfan64537 (#2156, #2352)
|
||||
- Bugfix: Fixed hidden tooltips when always on top is active (#2384)
|
||||
- Bugfix: Fix CLI arguments (`--help`, `--version`, `--channels`) not being respected (#2368, #2190)
|
||||
- Bugfix: Fixed search field not being focused on popup open (#2540)
|
||||
- Bugfix: Fix Twitch cheer emotes not displaying tooltips when hovered (#2434, #2503)
|
||||
- Bugfix: Fix BTTV/FFZ channel emotes saying unknown error when no emotes found (#2542)
|
||||
- Bugfix: Fix directory not opening when clicking "Open AppData Directory" setting button on macOS (#2531, #2537)
|
||||
- Bugfix: Fix quickswitcher not respecting order of tabs when filtering (#2519, #2561)
|
||||
- Bugfix: Fix GNOME not associating Chatterino's window with its desktop entry (#1863, #2587)
|
||||
- Bugfix: Fix buffer overflow in emoji parsing. (#2602)
|
||||
- Bugfix: Fix windows being brought back to life after the settings dialog was closed. (#1892, #2613)
|
||||
- Dev: Updated minimum required Qt framework version to 5.12. (#2210)
|
||||
- Dev: Migrated `Kraken::getUser` to Helix (#2260)
|
||||
- Dev: Migrated `TwitchAccount::(un)followUser` from Kraken to Helix and moved it to `Helix::(un)followUser`. (#2306)
|
||||
|
|
|
@ -4,6 +4,7 @@ include(FeatureSummary)
|
|||
|
||||
list(APPEND CMAKE_MODULE_PATH
|
||||
"${CMAKE_SOURCE_DIR}/cmake"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/sanitizers-cmake/cmake"
|
||||
)
|
||||
|
||||
project(chatterino VERSION 2.2.3)
|
||||
|
@ -44,6 +45,8 @@ if (WIN32)
|
|||
find_package(WinToast REQUIRED)
|
||||
endif ()
|
||||
|
||||
find_package(Sanitizers)
|
||||
|
||||
# Find boost on the system
|
||||
find_package(Boost REQUIRED)
|
||||
|
||||
|
|
1
cmake/sanitizers-cmake
Submodule
1
cmake/sanitizers-cmake
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 99e159ec9bc8dd362b08d18436bd40ff0648417b
|
|
@ -13,8 +13,7 @@
|
|||
</summary>
|
||||
<description>
|
||||
<p>
|
||||
Chatterino 2 is the second installment of the Twitch chat client series
|
||||
"Chatterino".
|
||||
Chatterino is a chat client for Twitch chat. It aims to be an improved/extended version of the Twitch web chat.
|
||||
</p>
|
||||
</description>
|
||||
<screenshots>
|
||||
|
|
|
@ -13,7 +13,7 @@ AB_SETTINGS_CLASS *AB_SETTINGS_CLASS::instance = nullptr;
|
|||
void _actuallyRegisterSetting(
|
||||
std::weak_ptr<pajlada::Settings::SettingData> setting)
|
||||
{
|
||||
_settings.push_back(setting);
|
||||
_settings.push_back(std::move(setting));
|
||||
}
|
||||
|
||||
AB_SETTINGS_CLASS::AB_SETTINGS_CLASS(const QString &settingsDirectory)
|
||||
|
|
|
@ -460,6 +460,7 @@ endif ()
|
|||
source_group(TREE ${CMAKE_SOURCE_DIR} FILES ${SOURCE_FILES})
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
|
||||
add_sanitizers(${PROJECT_NAME})
|
||||
|
||||
target_precompile_headers(${PROJECT_NAME} PRIVATE PrecompiledHeader.hpp)
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ void Args::applyCustomChannelLayout(const QString &argValue)
|
|||
return QRect(-1, -1, -1, -1);
|
||||
}();
|
||||
|
||||
window.geometry_ = std::move(configMainLayout);
|
||||
window.geometry_ = configMainLayout;
|
||||
|
||||
QStringList channelArgList = argValue.split(";");
|
||||
for (const QString &channelArg : channelArgList)
|
||||
|
|
|
@ -320,13 +320,13 @@ void Channel::onConnected()
|
|||
// Indirect channel
|
||||
//
|
||||
IndirectChannel::Data::Data(ChannelPtr _channel, Channel::Type _type)
|
||||
: channel(_channel)
|
||||
: channel(std::move(_channel))
|
||||
, type(_type)
|
||||
{
|
||||
}
|
||||
|
||||
IndirectChannel::IndirectChannel(ChannelPtr channel, Channel::Type type)
|
||||
: data_(std::make_unique<Data>(channel, type))
|
||||
: data_(std::make_unique<Data>(std::move(channel), type))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ void IndirectChannel::reset(ChannelPtr channel)
|
|||
{
|
||||
assert(this->data_->type != Channel::Type::Direct);
|
||||
|
||||
this->data_->channel = channel;
|
||||
this->data_->channel = std::move(channel);
|
||||
this->data_->changed.invoke();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace chatterino {
|
|||
|
||||
void _registerSetting(std::weak_ptr<pajlada::Settings::SettingData> setting)
|
||||
{
|
||||
_actuallyRegisterSetting(setting);
|
||||
_actuallyRegisterSetting(std::move(setting));
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -19,6 +19,7 @@ enum class NetworkRequestType {
|
|||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Patch,
|
||||
};
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -116,6 +116,19 @@ void loadUncached(const std::shared_ptr<NetworkData> &data)
|
|||
return NetworkManager::accessManager.post(
|
||||
data->request_, data->payload_);
|
||||
}
|
||||
case NetworkRequestType::Patch:
|
||||
if (data->multiPartPayload_)
|
||||
{
|
||||
assert(data->payload_.isNull());
|
||||
|
||||
return NetworkManager::accessManager.sendCustomRequest(
|
||||
data->request_, "PATCH", data->multiPartPayload_);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NetworkManager::accessManager.sendCustomRequest(
|
||||
data->request_, "PATCH", data->payload_);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}();
|
||||
|
|
|
@ -643,7 +643,85 @@ void CommandController::initialize(Settings &, Paths &paths)
|
|||
getApp()->windows->getMainWindow().getNotebook().getSelectedPage());
|
||||
|
||||
currentPage->getSelectedSplit()->getChannelView().clearMessages();
|
||||
return "";
|
||||
});
|
||||
|
||||
this->registerCommand("/settitle", [](const QStringList &words,
|
||||
ChannelPtr channel) {
|
||||
if (words.size() < 2)
|
||||
{
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Usage: /settitle <stream title>."));
|
||||
return "";
|
||||
}
|
||||
if (auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()))
|
||||
{
|
||||
auto status = twitchChannel->accessStreamStatus();
|
||||
auto title = words.mid(1).join(" ");
|
||||
getHelix()->updateChannel(
|
||||
twitchChannel->roomId(), "", "", title,
|
||||
[channel, title](NetworkResult) {
|
||||
channel->addMessage(makeSystemMessage(
|
||||
QString("Updated title to %1").arg(title)));
|
||||
},
|
||||
[channel] {
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Title update failed! Are you "
|
||||
"missing the required scope?"));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"Unable to set title of non-Twitch channel."));
|
||||
}
|
||||
return "";
|
||||
});
|
||||
this->registerCommand("/setgame", [](const QStringList &words,
|
||||
ChannelPtr channel) {
|
||||
if (words.size() < 2)
|
||||
{
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Usage: /setgame <stream game>."));
|
||||
return "";
|
||||
}
|
||||
if (auto twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()))
|
||||
{
|
||||
getHelix()->searchGames(
|
||||
words.mid(1).join(" "),
|
||||
[channel, twitchChannel](std::vector<HelixGame> games) {
|
||||
if (games.empty())
|
||||
{
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Game not found."));
|
||||
}
|
||||
else // 1 or more games
|
||||
{
|
||||
auto status = twitchChannel->accessStreamStatus();
|
||||
getHelix()->updateChannel(
|
||||
twitchChannel->roomId(), games.at(0).id, "", "",
|
||||
[channel, games](NetworkResult) {
|
||||
channel->addMessage(makeSystemMessage(
|
||||
QString("Updated game to %1")
|
||||
.arg(games.at(0).name)));
|
||||
},
|
||||
[channel] {
|
||||
channel->addMessage(makeSystemMessage(
|
||||
"Game update failed! Are you "
|
||||
"missing the required scope?"));
|
||||
});
|
||||
}
|
||||
},
|
||||
[channel] {
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Failed to look up game."));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->addMessage(
|
||||
makeSystemMessage("Unable to set game of non-Twitch channel."));
|
||||
}
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ HighlightPhrase::HighlightPhrase(const QString &pattern, bool showInMentions,
|
|||
, isRegex_(isRegex)
|
||||
, isCaseSensitive_(isCaseSensitive)
|
||||
, soundUrl_(soundUrl)
|
||||
, color_(color)
|
||||
, color_(std::move(color))
|
||||
, regex_(isRegex_
|
||||
? pattern
|
||||
: REGEX_START_BOUNDARY + QRegularExpression::escape(pattern) +
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace {
|
|||
} // namespace
|
||||
|
||||
MessageLayout::MessageLayout(MessagePtr message)
|
||||
: message_(message)
|
||||
: message_(std::move(message))
|
||||
, container_(std::make_shared<MessageLayoutContainer>())
|
||||
{
|
||||
DebugCount::increase("message layout");
|
||||
|
|
|
@ -88,7 +88,7 @@ FlagsEnum<MessageElementFlag> MessageLayoutElement::getFlags() const
|
|||
ImageLayoutElement::ImageLayoutElement(MessageElement &creator, ImagePtr image,
|
||||
const QSize &size)
|
||||
: MessageLayoutElement(creator, size)
|
||||
, image_(image)
|
||||
, image_(std::move(image))
|
||||
{
|
||||
this->trailingSpace = creator.hasTrailingSpace();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ const std::shared_ptr<QColor> ColorProvider::color(ColorType type) const
|
|||
void ColorProvider::updateColor(ColorType type, QColor color)
|
||||
{
|
||||
auto colorPtr = this->typeColorMap_.at(type);
|
||||
*colorPtr = color;
|
||||
*colorPtr = std::move(color);
|
||||
}
|
||||
|
||||
QSet<QColor> ColorProvider::recentColors() const
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace {
|
|||
const rapidjson::Value &unparsedEmoji,
|
||||
QString shortCode = QString())
|
||||
{
|
||||
static uint unicodeBytes[4];
|
||||
std::array<uint32_t, 7> unicodeBytes;
|
||||
|
||||
struct {
|
||||
bool apple;
|
||||
|
@ -91,11 +91,12 @@ namespace {
|
|||
|
||||
for (const QString &unicodeCharacter : unicodeCharacters)
|
||||
{
|
||||
unicodeBytes[numUnicodeBytes++] =
|
||||
unicodeBytes.at(numUnicodeBytes++) =
|
||||
QString(unicodeCharacter).toUInt(nullptr, 16);
|
||||
}
|
||||
|
||||
emojiData->value = QString::fromUcs4(unicodeBytes, numUnicodeBytes);
|
||||
emojiData->value =
|
||||
QString::fromUcs4(unicodeBytes.data(), numUnicodeBytes);
|
||||
}
|
||||
|
||||
// getToneNames takes a tones and returns their names in the same order
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "singletons/Settings.hpp"
|
||||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/FormatTime.hpp"
|
||||
#include "util/Helpers.hpp"
|
||||
#include "util/IrcHelpers.hpp"
|
||||
|
||||
#include <IrcMessage>
|
||||
|
@ -579,10 +580,11 @@ std::vector<MessagePtr> IrcMessageHandler::parseUserNoticeMessage(
|
|||
content = parameters[1];
|
||||
}
|
||||
|
||||
if (msgType == "sub" || msgType == "resub" || msgType == "subgift")
|
||||
if (msgType == "sub" || msgType == "resub" || msgType == "subgift" ||
|
||||
msgType == "bitsbadgetier")
|
||||
{
|
||||
// Sub-specific message. I think it's only allowed for "resub" messages
|
||||
// atm
|
||||
// Sub-specific and bits badge upgrade specific message.
|
||||
// It's only allowed for "resub" messages.
|
||||
if (!content.isEmpty())
|
||||
{
|
||||
MessageParseArgs args;
|
||||
|
@ -600,9 +602,18 @@ std::vector<MessagePtr> IrcMessageHandler::parseUserNoticeMessage(
|
|||
|
||||
if (it != tags.end())
|
||||
{
|
||||
auto b =
|
||||
MessageBuilder(systemMessage, parseTagString(it.value().toString()),
|
||||
calculateMessageTimestamp(message));
|
||||
QString messageText = it.value().toString();
|
||||
|
||||
if (msgType == "bitsbadgetier")
|
||||
{
|
||||
messageText = QString("%1 just earned a new %2 Bits badge!")
|
||||
.arg(tags.value("display-name").toString())
|
||||
.arg(kFormatNumbers(
|
||||
tags.value("msg-param-threshold").toInt()));
|
||||
}
|
||||
|
||||
auto b = MessageBuilder(systemMessage, parseTagString(messageText),
|
||||
calculateMessageTimestamp(message));
|
||||
|
||||
b->flags.set(MessageFlag::Subscription);
|
||||
auto newMessage = b.release();
|
||||
|
@ -628,10 +639,11 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
|||
content = parameters[1];
|
||||
}
|
||||
|
||||
if (msgType == "sub" || msgType == "resub" || msgType == "subgift")
|
||||
if (msgType == "sub" || msgType == "resub" || msgType == "subgift" ||
|
||||
msgType == "bitsbadgetier")
|
||||
{
|
||||
// Sub-specific message. I think it's only allowed for "resub" messages
|
||||
// atm
|
||||
// Sub-specific and bits badge upgrade specific message.
|
||||
// It's only allowed for "resub" messages.
|
||||
if (!content.isEmpty())
|
||||
{
|
||||
this->addMessage(message, target, content, server, true, false);
|
||||
|
@ -642,9 +654,18 @@ void IrcMessageHandler::handleUserNoticeMessage(Communi::IrcMessage *message,
|
|||
|
||||
if (it != tags.end())
|
||||
{
|
||||
auto b =
|
||||
MessageBuilder(systemMessage, parseTagString(it.value().toString()),
|
||||
calculateMessageTimestamp(message));
|
||||
QString messageText = it.value().toString();
|
||||
|
||||
if (msgType == "bitsbadgetier")
|
||||
{
|
||||
messageText = QString("%1 just earned a new %2 Bits badge!")
|
||||
.arg(tags.value("display-name").toString())
|
||||
.arg(kFormatNumbers(
|
||||
tags.value("msg-param-threshold").toInt()));
|
||||
}
|
||||
|
||||
auto b = MessageBuilder(systemMessage, parseTagString(messageText),
|
||||
calculateMessageTimestamp(message));
|
||||
|
||||
b->flags.set(MessageFlag::Subscription);
|
||||
auto newMessage = b.release();
|
||||
|
|
|
@ -64,7 +64,7 @@ QColor TwitchAccount::color()
|
|||
|
||||
void TwitchAccount::setColor(QColor color)
|
||||
{
|
||||
this->color_.set(color);
|
||||
this->color_.set(std::move(color));
|
||||
}
|
||||
|
||||
bool TwitchAccount::setOAuthClient(const QString &newClientID)
|
||||
|
@ -131,7 +131,7 @@ void TwitchAccount::blockUser(QString userId, std::function<void()> onSuccess,
|
|||
}
|
||||
onSuccess();
|
||||
},
|
||||
onFailure);
|
||||
std::move(onFailure));
|
||||
}
|
||||
|
||||
void TwitchAccount::unblockUser(QString userId, std::function<void()> onSuccess,
|
||||
|
@ -149,7 +149,7 @@ void TwitchAccount::unblockUser(QString userId, std::function<void()> onSuccess,
|
|||
}
|
||||
onSuccess();
|
||||
},
|
||||
onFailure);
|
||||
std::move(onFailure));
|
||||
}
|
||||
|
||||
void TwitchAccount::checkFollow(const QString targetUserID,
|
||||
|
|
|
@ -484,6 +484,7 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
|
|||
if (match.hasMatch())
|
||||
{
|
||||
QString username = match.captured(1);
|
||||
auto originalTextColor = textColor;
|
||||
|
||||
if (this->twitchChannel != nullptr && getSettings()->colorUsernames)
|
||||
{
|
||||
|
@ -495,13 +496,23 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
|
|||
}
|
||||
}
|
||||
|
||||
this->emplace<TextElement>(string, MessageElementFlag::BoldUsername,
|
||||
auto prefixedUsername = '@' + username;
|
||||
this->emplace<TextElement>(prefixedUsername,
|
||||
MessageElementFlag::BoldUsername,
|
||||
textColor, FontStyle::ChatMediumBold)
|
||||
->setLink({Link::UserInfo, username});
|
||||
->setLink({Link::UserInfo, username})
|
||||
->setTrailingSpace(false);
|
||||
|
||||
this->emplace<TextElement>(prefixedUsername,
|
||||
MessageElementFlag::NonBoldUsername,
|
||||
textColor)
|
||||
->setLink({Link::UserInfo, username})
|
||||
->setTrailingSpace(false);
|
||||
|
||||
this->emplace<TextElement>(string.remove(prefixedUsername),
|
||||
MessageElementFlag::Text,
|
||||
originalTextColor);
|
||||
|
||||
this->emplace<TextElement>(
|
||||
string, MessageElementFlag::NonBoldUsername, textColor)
|
||||
->setLink({Link::UserInfo, username});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -514,6 +525,8 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
|
|||
|
||||
if (match.hasMatch() && chatters->contains(username))
|
||||
{
|
||||
auto originalTextColor = textColor;
|
||||
|
||||
if (getSettings()->colorUsernames)
|
||||
{
|
||||
if (auto userColor =
|
||||
|
@ -524,13 +537,21 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)
|
|||
}
|
||||
}
|
||||
|
||||
this->emplace<TextElement>(string, MessageElementFlag::BoldUsername,
|
||||
this->emplace<TextElement>(username,
|
||||
MessageElementFlag::BoldUsername,
|
||||
textColor, FontStyle::ChatMediumBold)
|
||||
->setLink({Link::UserInfo, username});
|
||||
->setLink({Link::UserInfo, username})
|
||||
->setTrailingSpace(false);
|
||||
|
||||
this->emplace<TextElement>(
|
||||
string, MessageElementFlag::NonBoldUsername, textColor)
|
||||
->setLink({Link::UserInfo, username});
|
||||
username, MessageElementFlag::NonBoldUsername, textColor)
|
||||
->setLink({Link::UserInfo, username})
|
||||
->setTrailingSpace(false);
|
||||
|
||||
this->emplace<TextElement>(string.remove(username),
|
||||
MessageElementFlag::Text,
|
||||
originalTextColor);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ void Helix::getUserByName(QString userName,
|
|||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
QStringList userIds;
|
||||
QStringList userLogins{userName};
|
||||
QStringList userLogins{std::move(userName)};
|
||||
|
||||
this->fetchUsers(
|
||||
userIds, userLogins,
|
||||
|
@ -78,7 +78,7 @@ void Helix::getUserById(QString userId,
|
|||
ResultCallback<HelixUser> successCallback,
|
||||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
QStringList userIds{userId};
|
||||
QStringList userIds{std::move(userId)};
|
||||
QStringList userLogins;
|
||||
|
||||
this->fetchUsers(
|
||||
|
@ -136,7 +136,8 @@ void Helix::getUserFollowers(
|
|||
QString userId, ResultCallback<HelixUsersFollowsResponse> successCallback,
|
||||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
this->fetchUsersFollows("", userId, successCallback, failureCallback);
|
||||
this->fetchUsersFollows("", std::move(userId), std::move(successCallback),
|
||||
std::move(failureCallback));
|
||||
}
|
||||
|
||||
void Helix::getUserFollow(
|
||||
|
@ -145,7 +146,7 @@ void Helix::getUserFollow(
|
|||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
this->fetchUsersFollows(
|
||||
userId, targetId,
|
||||
std::move(userId), std::move(targetId),
|
||||
[successCallback](const auto &response) {
|
||||
if (response.data.empty())
|
||||
{
|
||||
|
@ -155,7 +156,7 @@ void Helix::getUserFollow(
|
|||
|
||||
successCallback(true, response.data[0]);
|
||||
},
|
||||
failureCallback);
|
||||
std::move(failureCallback));
|
||||
}
|
||||
|
||||
void Helix::fetchStreams(
|
||||
|
@ -209,7 +210,7 @@ void Helix::getStreamById(QString userId,
|
|||
ResultCallback<bool, HelixStream> successCallback,
|
||||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
QStringList userIds{userId};
|
||||
QStringList userIds{std::move(userId)};
|
||||
QStringList userLogins;
|
||||
|
||||
this->fetchStreams(
|
||||
|
@ -230,7 +231,7 @@ void Helix::getStreamByName(QString userName,
|
|||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
QStringList userIds;
|
||||
QStringList userLogins{userName};
|
||||
QStringList userLogins{std::move(userName)};
|
||||
|
||||
this->fetchStreams(
|
||||
userIds, userLogins,
|
||||
|
@ -295,11 +296,47 @@ void Helix::fetchGames(QStringList gameIds, QStringList gameNames,
|
|||
.execute();
|
||||
}
|
||||
|
||||
void Helix::searchGames(QString gameName,
|
||||
ResultCallback<std::vector<HelixGame>> successCallback,
|
||||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
QUrlQuery urlQuery;
|
||||
urlQuery.addQueryItem("query", gameName);
|
||||
|
||||
this->makeRequest("search/categories", urlQuery)
|
||||
.onSuccess([successCallback, failureCallback](auto result) -> Outcome {
|
||||
auto root = result.parseJson();
|
||||
auto data = root.value("data");
|
||||
|
||||
if (!data.isArray())
|
||||
{
|
||||
failureCallback();
|
||||
return Failure;
|
||||
}
|
||||
|
||||
std::vector<HelixGame> games;
|
||||
|
||||
for (const auto &jsonStream : data.toArray())
|
||||
{
|
||||
games.emplace_back(jsonStream.toObject());
|
||||
}
|
||||
|
||||
successCallback(games);
|
||||
|
||||
return Success;
|
||||
})
|
||||
.onError([failureCallback](auto /*result*/) {
|
||||
// TODO: make better xd
|
||||
failureCallback();
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
|
||||
void Helix::getGameById(QString gameId,
|
||||
ResultCallback<HelixGame> successCallback,
|
||||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
QStringList gameIds{gameId};
|
||||
QStringList gameIds{std::move(gameId)};
|
||||
QStringList gameNames;
|
||||
|
||||
this->fetchGames(
|
||||
|
@ -409,7 +446,7 @@ void Helix::createClip(QString channelId,
|
|||
break;
|
||||
}
|
||||
})
|
||||
.finally(finallyCallback)
|
||||
.finally(std::move(finallyCallback))
|
||||
.execute();
|
||||
}
|
||||
|
||||
|
@ -578,6 +615,48 @@ void Helix::unblockUser(QString targetUserId,
|
|||
.execute();
|
||||
}
|
||||
|
||||
void Helix::updateChannel(QString broadcasterId, QString gameId,
|
||||
QString language, QString title,
|
||||
std::function<void(NetworkResult)> successCallback,
|
||||
HelixFailureCallback failureCallback)
|
||||
{
|
||||
QUrlQuery urlQuery;
|
||||
auto data = QJsonDocument();
|
||||
auto obj = QJsonObject();
|
||||
if (!gameId.isEmpty())
|
||||
{
|
||||
obj.insert("game_id", gameId);
|
||||
}
|
||||
if (!language.isEmpty())
|
||||
{
|
||||
obj.insert("broadcaster_language", language);
|
||||
}
|
||||
if (!title.isEmpty())
|
||||
{
|
||||
obj.insert("title", title);
|
||||
}
|
||||
|
||||
if (title.isEmpty() && gameId.isEmpty() && language.isEmpty())
|
||||
{
|
||||
qCDebug(chatterinoCommon) << "Tried to update channel with no changes!";
|
||||
return;
|
||||
}
|
||||
|
||||
data.setObject(obj);
|
||||
urlQuery.addQueryItem("broadcaster_id", broadcasterId);
|
||||
this->makeRequest("channels", urlQuery)
|
||||
.type(NetworkRequestType::Patch)
|
||||
.header("Content-Type", "application/json")
|
||||
.payload(data.toJson())
|
||||
.onSuccess([successCallback, failureCallback](auto result) -> Outcome {
|
||||
successCallback(result);
|
||||
return Success;
|
||||
})
|
||||
.onError([failureCallback](NetworkResult result) {
|
||||
failureCallback();
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery)
|
||||
{
|
||||
assert(!url.startsWith("/"));
|
||||
|
@ -611,8 +690,8 @@ NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery)
|
|||
|
||||
void Helix::update(QString clientId, QString oauthToken)
|
||||
{
|
||||
this->clientId = clientId;
|
||||
this->oauthToken = oauthToken;
|
||||
this->clientId = std::move(clientId);
|
||||
this->oauthToken = std::move(oauthToken);
|
||||
}
|
||||
|
||||
void Helix::initialize()
|
||||
|
|
|
@ -252,6 +252,11 @@ public:
|
|||
ResultCallback<std::vector<HelixGame>> successCallback,
|
||||
HelixFailureCallback failureCallback);
|
||||
|
||||
// https://dev.twitch.tv/docs/api/reference#search-categories
|
||||
void searchGames(QString gameName,
|
||||
ResultCallback<std::vector<HelixGame>> successCallback,
|
||||
HelixFailureCallback failureCallback);
|
||||
|
||||
void getGameById(QString gameId, ResultCallback<HelixGame> successCallback,
|
||||
HelixFailureCallback failureCallback);
|
||||
|
||||
|
@ -296,6 +301,12 @@ public:
|
|||
std::function<void()> successCallback,
|
||||
HelixFailureCallback failureCallback);
|
||||
|
||||
// https://dev.twitch.tv/docs/api/reference#modify-channel-information
|
||||
void updateChannel(QString broadcasterId, QString gameId, QString language,
|
||||
QString title,
|
||||
std::function<void(NetworkResult)> successCallback,
|
||||
HelixFailureCallback failureCallback);
|
||||
|
||||
void update(QString clientId, QString oauthToken);
|
||||
|
||||
static void initialize();
|
||||
|
|
|
@ -63,8 +63,8 @@ NetworkRequest Kraken::makeRequest(QString url, QUrlQuery urlQuery)
|
|||
|
||||
void Kraken::update(QString clientId, QString oauthToken)
|
||||
{
|
||||
this->clientId = clientId;
|
||||
this->oauthToken = oauthToken;
|
||||
this->clientId = std::move(clientId);
|
||||
this->oauthToken = std::move(oauthToken);
|
||||
}
|
||||
|
||||
void Kraken::initialize()
|
||||
|
|
|
@ -104,6 +104,16 @@ URL: https://dev.twitch.tv/docs/api/reference#get-channel-information
|
|||
Used in:
|
||||
- `TwitchChannel` to refresh stream title
|
||||
|
||||
### Update Channel
|
||||
|
||||
URL: https://dev.twitch.tv/docs/api/reference#modify-channel-information
|
||||
Requires `channel:manage:broadcast` scope
|
||||
|
||||
- We implement this in `providers/twitch/api/Helix.cpp updateChannel`
|
||||
Used in:
|
||||
- `/setgame` to update the game in the current channel
|
||||
- `/settitle` to update the title in the current channel
|
||||
|
||||
### Create Stream Marker
|
||||
|
||||
URL: https://dev.twitch.tv/docs/api/reference/#create-stream-marker
|
||||
|
@ -142,6 +152,14 @@ Requires `user:manage:blocked_users` scope
|
|||
- `widgets/dialogs/UserInfoPopup.cpp` to unblock a user via checkbox in the usercard
|
||||
- `controllers/commands/CommandController.cpp` to unblock a user via "/unblock" command
|
||||
|
||||
### Search Categories
|
||||
|
||||
URL: https://dev.twitch.tv/docs/api/reference#search-categories
|
||||
|
||||
- We implement this in `providers/twitch/api/Helix.cpp searchGames`
|
||||
Used in:
|
||||
- `controllers/commands/CommandController.cpp` in `/setgame` command to fuzzy search for game titles
|
||||
|
||||
## TMI
|
||||
|
||||
The TMI api is undocumented.
|
||||
|
|
|
@ -33,7 +33,7 @@ TooltipPreviewImage::TooltipPreviewImage()
|
|||
|
||||
void TooltipPreviewImage::setImage(ImagePtr image)
|
||||
{
|
||||
this->image_ = image;
|
||||
this->image_ = std::move(image);
|
||||
|
||||
this->refreshTooltipWidgetPixmap();
|
||||
}
|
||||
|
|
|
@ -42,4 +42,9 @@ QString localizeNumbers(const int &number)
|
|||
return locale.toString(number);
|
||||
}
|
||||
|
||||
QString kFormatNumbers(const int &number)
|
||||
{
|
||||
return QString("%1K").arg(number / 1000);
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -15,4 +15,6 @@ QString shortenString(const QString &str, unsigned maxWidth = 50);
|
|||
|
||||
QString localizeNumbers(const int &number);
|
||||
|
||||
QString kFormatNumbers(const int &number);
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -17,7 +17,7 @@ class LambdaRunnable : public QRunnable
|
|||
public:
|
||||
LambdaRunnable(std::function<void()> action)
|
||||
{
|
||||
this->action_ = action;
|
||||
this->action_ = std::move(action);
|
||||
}
|
||||
|
||||
void run()
|
||||
|
|
|
@ -143,7 +143,7 @@ void AttachedWindow::detach(const QString &winId)
|
|||
|
||||
void AttachedWindow::setChannel(ChannelPtr channel)
|
||||
{
|
||||
this->ui_.split->setChannel(channel);
|
||||
this->ui_.split->setChannel(std::move(channel));
|
||||
}
|
||||
|
||||
void AttachedWindow::showEvent(QShowEvent *)
|
||||
|
|
|
@ -244,7 +244,10 @@ void BaseWindow::init()
|
|||
getSettings()->windowTopMost.connect(
|
||||
[this](bool topMost, auto) {
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, topMost);
|
||||
this->show();
|
||||
if (this->isVisible())
|
||||
{
|
||||
this->show();
|
||||
}
|
||||
},
|
||||
this->managedConnections_);
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
namespace chatterino {
|
||||
|
||||
Label::Label(QString text, FontStyle style)
|
||||
: Label(nullptr, text, style)
|
||||
: Label(nullptr, std::move(text), style)
|
||||
{
|
||||
}
|
||||
|
||||
Label::Label(BaseWidget *parent, QString text, FontStyle style)
|
||||
: BaseWidget(parent)
|
||||
, text_(text)
|
||||
, text_(std::move(text))
|
||||
, fontStyle_(style)
|
||||
{
|
||||
this->connections_.managedConnect(getFonts()->fontChanged, [this] {
|
||||
|
|
|
@ -26,7 +26,7 @@ StreamView::StreamView(ChannelPtr channel, const QUrl &url)
|
|||
|
||||
auto chat = layoutCreator.emplace<ChannelView>();
|
||||
chat->setFixedWidth(300);
|
||||
chat->setChannel(channel);
|
||||
chat->setChannel(std::move(channel));
|
||||
|
||||
this->layout()->setSpacing(0);
|
||||
this->layout()->setMargin(0);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "singletons/WindowManager.hpp"
|
||||
#include "util/Shortcut.hpp"
|
||||
#include "widgets/Notebook.hpp"
|
||||
#include "widgets/Scrollbar.hpp"
|
||||
#include "widgets/helper/ChannelView.hpp"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
@ -178,6 +179,20 @@ EmotePopup::EmotePopup(QWidget *parent)
|
|||
createWindowShortcut(this, "CTRL+Shift+Tab", [=] {
|
||||
notebook->selectPreviousTab();
|
||||
});
|
||||
|
||||
// Scroll with Page Up / Page Down
|
||||
createWindowShortcut(this, "PgUp", [=] {
|
||||
auto &scrollbar =
|
||||
dynamic_cast<ChannelView *>(notebook->getSelectedPage())
|
||||
->getScrollBar();
|
||||
scrollbar.offset(-scrollbar.getLargeChange());
|
||||
});
|
||||
createWindowShortcut(this, "PgDown", [=] {
|
||||
auto &scrollbar =
|
||||
dynamic_cast<ChannelView *>(notebook->getSelectedPage())
|
||||
->getScrollBar();
|
||||
scrollbar.offset(scrollbar.getLargeChange());
|
||||
});
|
||||
}
|
||||
|
||||
void EmotePopup::loadChannel(ChannelPtr _channel)
|
||||
|
|
|
@ -45,7 +45,7 @@ void NotificationPopup::updatePosition()
|
|||
|
||||
void NotificationPopup::addMessage(MessagePtr msg)
|
||||
{
|
||||
this->channel_->addMessage(msg);
|
||||
this->channel_->addMessage(std::move(msg));
|
||||
|
||||
// QTimer::singleShot(5000, this, [this, msg] { this->channel->remove });
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ Button::Button(BaseWidget *parent)
|
|||
|
||||
void Button::setMouseEffectColor(boost::optional<QColor> color)
|
||||
{
|
||||
this->mouseEffectColor_ = color;
|
||||
this->mouseEffectColor_ = std::move(color);
|
||||
}
|
||||
|
||||
void Button::setPixmap(const QPixmap &_pixmap)
|
||||
|
|
|
@ -550,7 +550,7 @@ bool ChannelView::getEnableScrollingToBottom() const
|
|||
|
||||
void ChannelView::setOverrideFlags(boost::optional<MessageElementFlags> value)
|
||||
{
|
||||
this->overrideFlags_ = value;
|
||||
this->overrideFlags_ = std::move(value);
|
||||
}
|
||||
|
||||
const boost::optional<MessageElementFlags> &ChannelView::getOverrideFlags()
|
||||
|
@ -647,7 +647,7 @@ void ChannelView::setChannel(ChannelPtr underlyingChannel)
|
|||
this->channelConnections_.push_back(this->channel_->messageAppended.connect(
|
||||
[this](MessagePtr &message,
|
||||
boost::optional<MessageFlags> overridingFlags) {
|
||||
this->messageAppended(message, overridingFlags);
|
||||
this->messageAppended(message, std::move(overridingFlags));
|
||||
}));
|
||||
|
||||
this->channelConnections_.push_back(
|
||||
|
@ -753,7 +753,7 @@ ChannelPtr ChannelView::sourceChannel() const
|
|||
|
||||
void ChannelView::setSourceChannel(ChannelPtr sourceChannel)
|
||||
{
|
||||
this->sourceChannel_ = sourceChannel;
|
||||
this->sourceChannel_ = std::move(sourceChannel);
|
||||
}
|
||||
|
||||
bool ChannelView::hasSourceChannel() const
|
||||
|
|
|
@ -66,7 +66,7 @@ SearchPopup::SearchPopup(QWidget *parent)
|
|||
|
||||
void SearchPopup::setChannelFilters(FilterSetPtr filters)
|
||||
{
|
||||
this->channelFilters_ = filters;
|
||||
this->channelFilters_ = std::move(filters);
|
||||
}
|
||||
|
||||
void SearchPopup::setChannel(const ChannelPtr &channel)
|
||||
|
@ -155,6 +155,8 @@ void SearchPopup::initLayout()
|
|||
|
||||
this->setLayout(layout1);
|
||||
}
|
||||
|
||||
this->searchInput_->setFocus();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<MessagePredicate>> SearchPopup::parsePredicates(
|
||||
|
|
|
@ -45,6 +45,7 @@ add_executable(${PROJECT_NAME}
|
|||
${chatterino_SOURCES}
|
||||
${test_SOURCES}
|
||||
)
|
||||
add_sanitizers(${PROJECT_NAME})
|
||||
|
||||
# Enable autogeneration of Qts MOC/RCC/UIC
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
|
|
Loading…
Reference in a new issue