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 into feature/lua_scripting
This commit is contained in:
commit
debd7aaa51
33 changed files with 303 additions and 90 deletions
9
.CI/chatterino-nightly.flatpakref
Normal file
9
.CI/chatterino-nightly.flatpakref
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Flatpak Ref]
|
||||||
|
Name=com.chatterino.chatterino
|
||||||
|
Branch=nightly
|
||||||
|
Title=com.chatterino.chatterino from flathub
|
||||||
|
IsRuntime=false
|
||||||
|
Url=https://dl.flathub.org/repo/
|
||||||
|
SuggestRemoteName=flathub
|
||||||
|
GPGKey=mQINBFlD2sABEADsiUZUOYBg1UdDaWkEdJYkTSZD68214m8Q1fbrP5AptaUfCl8KYKFMNoAJRBXn9FbE6q6VBzghHXj/rSnA8WPnkbaEWR7xltOqzB1yHpCQ1l8xSfH5N02DMUBSRtD/rOYsBKbaJcOgW0K21sX+BecMY/AI2yADvCJEjhVKrjR9yfRX+NQEhDcbXUFRGt9ZT+TI5yT4xcwbvvTu7aFUR/dH7+wjrQ7lzoGlZGFFrQXSs2WI0WaYHWDeCwymtohXryF8lcWQkhH8UhfNJVBJFgCY8Q6UHkZG0FxMu8xnIDBMjBmSZKwKQn0nwzwM2afskZEnmNPYDI8nuNsSZBZSAw+ThhkdCZHZZRwzmjzyRuLLVFpOj3XryXwZcSefNMPDkZAuWWzPYjxS80cm2hG1WfqrG0Gl8+iX69cbQchb7gbEb0RtqNskTo9DDmO0bNKNnMbzmIJ3/rTbSahKSwtewklqSP/01o0WKZiy+n/RAkUKOFBprjJtWOZkc8SPXV/rnoS2dWsJWQZhuPPtv3tefdDiEyp7ePrfgfKxuHpZES0IZRiFI4J/nAUP5bix+srcIxOVqAam68CbAlPvWTivRUMRVbKjJiGXIOJ78wAMjqPg3QIC0GQ0EPAWwAOzzpdgbnG7TCQetaVV8rSYCuirlPYN+bJIwBtkOC9SWLoPMVZTwQARAQABtC5GbGF0aHViIFJlcG8gU2lnbmluZyBLZXkgPGZsYXRodWJAZmxhdGh1Yi5vcmc+iQJUBBMBCAA+FiEEblwF2XnHba+TwIE1QYTdTZB6fK4FAllD2sACGwMFCRLMAwAFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQQYTdTZB6fK5RJQ/+Ptd4sWxaiAW91FFk7+wmYOkEe1NY2UDNJjEEz34PNP/1RoxveHDt43kYJQ23OWaPJuZAbu+fWtjRYcMBzOsMCaFcRSHFiDIC9aTp4ux/mo+IEeyarYt/oyKb5t5lta6xaAqg7rwt65jW5/aQjnS4h7eFZ+dAKta7Y/fljNrOznUp81/SMcx4QA5G2Pw0hs4Xrxg59oONOTFGBgA6FF8WQghrpR7SnEe0FSEOVsAjwQ13Cfkfa7b70omXSWp7GWfUzgBKyoWxKTqzMN3RQHjjhPJcsQnrqH5enUu4Pcb2LcMFpzimHnUgb9ft72DP5wxfzHGAWOUiUXHbAekfq5iFks8cha/RST6wkxG3Rf44Zn09aOxh1btMcGL+5xb1G0BuCQnA0fP/kDYIPwh9z22EqwRQOspIcvGeLVkFeIfubxpcMdOfQqQnZtHMCabV5Q/Rk9K1ZGc8M2hlg8gHbXMFch2xJ0Wu72eXbA/UY5MskEeBgawTQnQOK/vNm7t0AJMpWK26Qg6178UmRghmeZDj9uNRc3EI1nSbgvmGlpDmCxaAGqaGL1zW4KPW5yN25/qeqXcgCvUjZLI9PNq3Kvizp1lUrbx7heRiSoazCucvHQ1VHUzcPVLUKKTkoTP8okThnRRRsBcZ1+jI4yMWIDLOCT7IW3FePr+3xyuy5eEo9a25Ag0EWUPa7AEQALT/CmSyZ8LWlRYQZKYw417p7Z2hxqd6TjwkwM3IQ1irumkWcTZBZIbBgrSOg6CcXD2oWydCQHWi9qaxhuhEl2bJL5LskmBcMxVdQeD0LLHd8QUnbnnIby8ocvWN1alPfvJFjCUTrmD22U1ycOzRw2lIe4kiQONbOZtdWrVImQQSndjFlisitbmlWHvHm2lOOYy8+GJB7YffVV193hmnBSJffCy4bvkuLxsI+n1DhOzc7MPV3z6HGk4HiEcF0yyt9tCYhpsxHFdBoq2h771HfAcS0s98EVAqYMFnf9em+4cnYpdI6mhIfS1FQiKl6DBAYA8tT3ggla00DurPo0JwX/zN+PaO5h/6O9aCZwV7G6rbkgMuqMergXaf8oP38gr0z+MqWnkfM63Bodq68GP4l4hd02BoFBbDf38TMuGQB14+twJMdfbAxo2MbgluvQgfwHfZ2ca6gyEY+9s/YD1gugLjV+S6CB51WkFNe1z4tAPgJZNxUcKCbeaHNbthl8Hks/pY9RCEseX/EdfzF18epbSjJMPh4DPQXbUoFwmyuYcoBOPmvZHNl9hK7B/1RP8w1ZrXk8qdupC0SNbafX7270B7lMMVImzZetGsM9ypXJ6llhp3FwW09iseNyGJGPsr/dvTMGDXqOPfU/9SAS1LSTY4K9PbRtdrBE318YX8mIk5ABEBAAGJBHIEGAEIACYWIQRuXAXZecdtr5PAgTVBhN1NkHp8rgUCWUPa7AIbAgUJEswDAAJACRBBhN1NkHp8rsF0IAQZAQgAHRYhBFSmzd2JGfsgQgDYrFYnAunj7X7oBQJZQ9rsAAoJEFYnAunj7X7oR6AP/0KYmiAFeqx14Z43/6s2gt3VhxlSd8bmcVV7oJFbMhdHBIeWBp2BvsUf00I0Zl14ZkwCKfLwbbORC2eIxvzJ+QWjGfPhDmS4XUSmhlXxWnYEveSek5Tde+fmu6lqKM8CHg5BNx4GWIX/vdLi1wWJZyhrUwwICAxkuhKxuP2Z1An48930eslTD2GGcjByc27+9cIZjHKa07I/aLffo04V+oMT9/tgzoquzgpVV4jwekADo2MJjhkkPveSNI420bgT+Q7Fi1l0X1aFUniBvQMsaBa27PngWm6xE2ZYvh7nWCdd5g0c0eLIHxWwzV1lZ4Ryx4ITO/VL25ItECcjhTRdYa64sA62MYSaB0x3eR+SihpgP3wSNPFu3MJo6FKTFdi4CBAEmpWHFW7FcRmd+cQXeFrHLN3iNVWryy0HK/CUEJmiZEmpNiXecl4vPIIuyF0zgSCztQtKoMr+injpmQGC/rF/ELBVZTUSLNB350S0Ztvw0FKWDAJSxFmoxt3xycqvvt47rxTrhi78nkk6jATKGyvP55sO+K7Q7Wh0DXA69hvPrYW2eu8jGCdVGxi6HX7L1qcfEd0378S71dZ3g9o6KKl1OsDWWQ6MJ6FGBZedl/ibRfs8p5+sbCX3lQSjEFy3rx6n0rUrXx8U2qb+RCLzJlmC5MNBOTDJwHPcX6gKsUcXZrEQALmRHoo3SrewO41RCr+5nUlqiqV3AohBMhnQbGzyHf2+drutIaoh7Rj80XRh2bkkuPLwlNPf+bTXwNVGse4bej7B3oV6Ae1N7lTNVF4Qh+1OowtGjmfJPWo0z1s6HFJVxoIof9z58Msvgao0zrKGqaMWaNQ6LUeC9g9Aj/9Uqjbo8X54aLiYs8Z1WNc06jKP+gv8AWLtv6CR+l2kLez1YMDucjm7v6iuCMVAmZdmxhg5I/X2+OM3vBsqPDdQpr2TPDLX3rCrSBiS0gOQ6DwN5N5QeTkxmY/7QO8bgLo/Wzu1iilH4vMKW6LBKCaRx5UEJxKpL4wkgITsYKneIt3NTHo5EOuaYk+y2+Dvt6EQFiuMsdbfUjs3seIHsghX/cbPJa4YUqZAL8C4OtVHaijwGo0ymt9MWvS9yNKMyT0JhN2/BdeOVWrHk7wXXJn/ZjpXilicXKPx4udCF76meE+6N2u/T+RYZ7fP1QMEtNZNmYDOfA6sViuPDfQSHLNbauJBo/n1sRYAsL5mcG22UDchJrlKvmK3EOADCQg+myrm8006LltubNB4wWNzHDJ0Ls2JGzQZCd/xGyVmUiidCBUrD537WdknOYE4FD7P0cHaM9brKJ/M8LkEH0zUlo73bY4XagbnCqve6PvQb5G2Z55qhWphd6f4B6DGed86zJEa/RhS
|
||||||
|
RuntimeRepo=https://dl.flathub.org/repo/flathub.flatpakrepo
|
38
.github/workflows/build.yml
vendored
38
.github/workflows/build.yml
vendored
|
@ -14,6 +14,8 @@ concurrency:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
C2_ENABLE_LTO: ${{ github.ref == 'refs/heads/master' }}
|
C2_ENABLE_LTO: ${{ github.ref == 'refs/heads/master' }}
|
||||||
|
CHATTERINO_REQUIRE_CLEAN_GIT: On
|
||||||
|
C2_BUILD_WITH_QT6: Off
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
@ -39,6 +41,11 @@ jobs:
|
||||||
qt-version: 5.15.2
|
qt-version: 5.15.2
|
||||||
pch: true
|
pch: true
|
||||||
force-lto: false
|
force-lto: false
|
||||||
|
# Ubuntu 22.04, Qt 6.2.4
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
qt-version: 6.2.4
|
||||||
|
pch: false
|
||||||
|
force-lto: false
|
||||||
# Test for disabling Precompiled Headers & enabling link-time optimization
|
# Test for disabling Precompiled Headers & enabling link-time optimization
|
||||||
- os: ubuntu-22.04
|
- os: ubuntu-22.04
|
||||||
qt-version: 5.15.2
|
qt-version: 5.15.2
|
||||||
|
@ -101,18 +108,33 @@ jobs:
|
||||||
echo "vs_version=2022" >> "$GITHUB_ENV"
|
echo "vs_version=2022" >> "$GITHUB_ENV"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
- name: Set BUILD_WITH_QT6
|
||||||
|
if: startsWith(matrix.qt-version, '6.')
|
||||||
|
run: |
|
||||||
|
echo "C2_BUILD_WITH_QT6=ON" >> "$GITHUB_ENV"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
fetch-depth: 0 # allows for tags access
|
fetch-depth: 0 # allows for tags access
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt5
|
||||||
uses: jurplel/install-qt-action@v3.0.0
|
if: startsWith(matrix.qt-version, '5.')
|
||||||
|
uses: jurplel/install-qt-action@v3.1.0
|
||||||
with:
|
with:
|
||||||
cache: true
|
cache: true
|
||||||
cache-key-prefix: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}
|
cache-key-prefix: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}-v2
|
||||||
|
version: ${{ matrix.qt-version }}
|
||||||
|
|
||||||
|
- name: Install Qt6
|
||||||
|
if: startsWith(matrix.qt-version, '6.')
|
||||||
|
uses: jurplel/install-qt-action@v3.1.0
|
||||||
|
with:
|
||||||
|
cache: true
|
||||||
|
cache-key-prefix: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}-v2
|
||||||
|
modules: qt5compat
|
||||||
version: ${{ matrix.qt-version }}
|
version: ${{ matrix.qt-version }}
|
||||||
dir: "${{ github.workspace }}/qt/"
|
|
||||||
|
|
||||||
# WINDOWS
|
# WINDOWS
|
||||||
- name: Cache conan packages part 1
|
- name: Cache conan packages part 1
|
||||||
|
@ -161,6 +183,7 @@ jobs:
|
||||||
-DBUILD_WITH_CRASHPAD="$Env:C2_ENABLE_CRASHPAD" `
|
-DBUILD_WITH_CRASHPAD="$Env:C2_ENABLE_CRASHPAD" `
|
||||||
-DCHATTERINO_LTO="$Env:C2_ENABLE_LTO" `
|
-DCHATTERINO_LTO="$Env:C2_ENABLE_LTO" `
|
||||||
-DCHATTERINO_PLUGINS="$Env:C2_PLUGINS" `
|
-DCHATTERINO_PLUGINS="$Env:C2_PLUGINS" `
|
||||||
|
-DBUILD_WITH_QT6="$Env:C2_BUILD_WITH_QT6" `
|
||||||
..
|
..
|
||||||
set cl=/MP
|
set cl=/MP
|
||||||
nmake /S /NOLOGO
|
nmake /S /NOLOGO
|
||||||
|
@ -247,6 +270,7 @@ jobs:
|
||||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=On \
|
-DCMAKE_EXPORT_COMPILE_COMMANDS=On \
|
||||||
-DCHATTERINO_LTO="$C2_ENABLE_LTO" \
|
-DCHATTERINO_LTO="$C2_ENABLE_LTO" \
|
||||||
-DCHATTERINO_PLUGINS="$C2_PLUGINS" \
|
-DCHATTERINO_PLUGINS="$C2_PLUGINS" \
|
||||||
|
-DBUILD_WITH_QT6="$C2_BUILD_WITH_QT6" \
|
||||||
..
|
..
|
||||||
make -j"$(nproc)"
|
make -j"$(nproc)"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -323,6 +347,7 @@ jobs:
|
||||||
-DUSE_PRECOMPILED_HEADERS=${{ matrix.pch }} \
|
-DUSE_PRECOMPILED_HEADERS=${{ matrix.pch }} \
|
||||||
-DCHATTERINO_LTO="$C2_ENABLE_LTO" \
|
-DCHATTERINO_LTO="$C2_ENABLE_LTO" \
|
||||||
-DCHATTERINO_PLUGINS="$C2_PLUGINS" \
|
-DCHATTERINO_PLUGINS="$C2_PLUGINS" \
|
||||||
|
-DBUILD_WITH_QT6="$C2_BUILD_WITH_QT6" \
|
||||||
..
|
..
|
||||||
make -j"$(sysctl -n hw.logicalcpu)"
|
make -j"$(sysctl -n hw.logicalcpu)"
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -382,6 +407,11 @@ jobs:
|
||||||
name: chatterino-osx-5.15.2.dmg
|
name: chatterino-osx-5.15.2.dmg
|
||||||
path: release-artifacts/
|
path: release-artifacts/
|
||||||
|
|
||||||
|
- name: Copy flatpakref
|
||||||
|
run: |
|
||||||
|
cp .CI/chatterino-nightly.flatpakref release-artifacts/
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: ncipollo/release-action@v1.12.0
|
uses: ncipollo/release-action@v1.12.0
|
||||||
with:
|
with:
|
||||||
|
|
5
.github/workflows/homebrew.yml
vendored
5
.github/workflows/homebrew.yml
vendored
|
@ -11,6 +11,7 @@ on:
|
||||||
env:
|
env:
|
||||||
# This gets updated later on in the run by a bash script to strip the prefix
|
# This gets updated later on in the run by a bash script to strip the prefix
|
||||||
C2_CASK_NAME: chatterino
|
C2_CASK_NAME: chatterino
|
||||||
|
# The full version of Chatterino (e.g. v2.4.1)
|
||||||
C2_TAGGED_VERSION: ${{ github.ref_name }}
|
C2_TAGGED_VERSION: ${{ github.ref_name }}
|
||||||
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
|
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
|
||||||
|
|
||||||
|
@ -23,4 +24,6 @@ jobs:
|
||||||
- name: Execute brew bump-cask-pr with version
|
- name: Execute brew bump-cask-pr with version
|
||||||
run: |
|
run: |
|
||||||
echo "Running bump-cask-pr for cask '$C2_CASK_NAME' and version '$C2_TAGGED_VERSION'"
|
echo "Running bump-cask-pr for cask '$C2_CASK_NAME' and version '$C2_TAGGED_VERSION'"
|
||||||
brew bump-cask-pr --version "$C2_TAGGED_VERSION" "$C2_CASK_NAME"
|
C2_TAGGED_VERSION_STRIPPED="${C2_TAGGED_VERSION:1}"
|
||||||
|
echo "Stripped version: '$C2_TAGGED_VERSION_STRIPPED'"
|
||||||
|
brew bump-cask-pr --version "$C2_TAGGED_VERSION_STRIPPED" "$C2_CASK_NAME"
|
||||||
|
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
@ -34,7 +34,7 @@ jobs:
|
||||||
key: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}
|
key: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v3.0.0
|
uses: jurplel/install-qt-action@v3.1.0
|
||||||
with:
|
with:
|
||||||
cache: true
|
cache: true
|
||||||
cache-key-prefix: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}
|
cache-key-prefix: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -118,3 +118,6 @@ qt6.natvis
|
||||||
|
|
||||||
# Autogenerated resource file
|
# Autogenerated resource file
|
||||||
resources/resources_autogenerated.qrc
|
resources/resources_autogenerated.qrc
|
||||||
|
|
||||||
|
# Leftovers from running `aqt install`
|
||||||
|
aqtinstall.log
|
||||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
## Unversioned
|
## Unversioned
|
||||||
|
|
||||||
|
- Minor: Delete all but the last 5 crashdumps on application start. (#4392)
|
||||||
|
- Dev: Add capability to build Chatterino with Qt6. (#4393)
|
||||||
|
- Dev: Fix homebrew update action. (#4394)
|
||||||
|
|
||||||
|
## 2.4.1
|
||||||
|
|
||||||
- Major: Added live emote updates for BTTV. (#4147)
|
- Major: Added live emote updates for BTTV. (#4147)
|
||||||
- Minor: Added setting to turn off rendering of reply context. (#4224)
|
- Minor: Added setting to turn off rendering of reply context. (#4224)
|
||||||
- Minor: Changed the highlight order to prioritize Message highlights over User highlights. (#4303)
|
- Minor: Changed the highlight order to prioritize Message highlights over User highlights. (#4303)
|
||||||
|
@ -14,9 +20,10 @@
|
||||||
- Minor: Added channel name to /mentions log entries. (#4371)
|
- Minor: Added channel name to /mentions log entries. (#4371)
|
||||||
- Minor: Added link to streamlink docs for easier user setup. (#4217)
|
- Minor: Added link to streamlink docs for easier user setup. (#4217)
|
||||||
- Minor: Added support for HTTP and Socks5 proxies through environment variables. (#4321)
|
- Minor: Added support for HTTP and Socks5 proxies through environment variables. (#4321)
|
||||||
- Minor: Removed sending part of the multipart emoji workaround. (#4361)
|
|
||||||
- Minor: Added crashpad to capture crashes on Windows locally. See PR for build/crash analysis instructions. (#4351)
|
- Minor: Added crashpad to capture crashes on Windows locally. See PR for build/crash analysis instructions. (#4351)
|
||||||
|
- Minor: Github releases now include flatpakref files for nightly builds
|
||||||
- Bugfix: Fixed User Card moderation actions not working after Twitch IRC chat command deprecation. (#4378)
|
- Bugfix: Fixed User Card moderation actions not working after Twitch IRC chat command deprecation. (#4378)
|
||||||
|
- Bugfix: Fixed User Card broadcaster actions (mod, unmod, vip, unvip) not working after Twitch IRC chat command deprecation. (#4387)
|
||||||
- Bugfix: Fixed crash that would occur when performing certain actions after removing all tabs. (#4271)
|
- Bugfix: Fixed crash that would occur when performing certain actions after removing all tabs. (#4271)
|
||||||
- Bugfix: Fixed highlight sounds not reloading on change properly. (#4194)
|
- Bugfix: Fixed highlight sounds not reloading on change properly. (#4194)
|
||||||
- Bugfix: Fixed CTRL + C not working in reply thread popups. (#4209)
|
- Bugfix: Fixed CTRL + C not working in reply thread popups. (#4209)
|
||||||
|
@ -33,8 +40,10 @@
|
||||||
- Bugfix: Fixed the split "Search" menu action not opening the correct search window. (#4305)
|
- Bugfix: Fixed the split "Search" menu action not opening the correct search window. (#4305)
|
||||||
- Bugfix: Fixed an issue on Windows when opening links in incognito mode that contained forward slashes in hash (#4307)
|
- Bugfix: Fixed an issue on Windows when opening links in incognito mode that contained forward slashes in hash (#4307)
|
||||||
- Bugfix: Fixed an issue where beta versions wouldn't update to stable versions correctly. (#4329)
|
- Bugfix: Fixed an issue where beta versions wouldn't update to stable versions correctly. (#4329)
|
||||||
|
- Bugfix: Fixed builds from GitHub showing up as modified. (#4384)
|
||||||
- Bugfix: Avoided crash that could occur when receiving channel point reward information. (#4360)
|
- Bugfix: Avoided crash that could occur when receiving channel point reward information. (#4360)
|
||||||
- Dev: Changed sound backend from Qt to miniaudio. (#4334)
|
- Dev: Changed sound backend from Qt to miniaudio. (#4334)
|
||||||
|
- Dev: Removed sending part of the multipart emoji workaround. (#4361)
|
||||||
- Dev: Removed protocol from QApplication's Organization Domain (so changed from `https://www.chatterino.com` to `chatterino.com`). (#4256)
|
- Dev: Removed protocol from QApplication's Organization Domain (so changed from `https://www.chatterino.com` to `chatterino.com`). (#4256)
|
||||||
- Dev: Ignore `WM_SHOWWINDOW` hide events, causing fewer attempted rescales. (#4198)
|
- Dev: Ignore `WM_SHOWWINDOW` hide events, causing fewer attempted rescales. (#4198)
|
||||||
- Dev: Migrated to C++ 20 (#4252, #4257)
|
- Dev: Migrated to C++ 20 (#4252, #4257)
|
||||||
|
@ -147,6 +156,7 @@
|
||||||
- Bugfix: Fixed crash happening when QuickSwitcher is used with a popout window. (#4187)
|
- Bugfix: Fixed crash happening when QuickSwitcher is used with a popout window. (#4187)
|
||||||
- Bugfix: Fixed low contrast of text in settings tooltips. (#4188)
|
- Bugfix: Fixed low contrast of text in settings tooltips. (#4188)
|
||||||
- Bugfix: Fixed being unable to see the usercard of VIPs who have Asian language display names. (#4174)
|
- Bugfix: Fixed being unable to see the usercard of VIPs who have Asian language display names. (#4174)
|
||||||
|
- Bugfix: Fixed whispers always being shown in the /mentions split. (#4389)
|
||||||
- Bugfix: Fixed messages where Right-to-Left order is mixed in multiple lines. (#4173)
|
- Bugfix: Fixed messages where Right-to-Left order is mixed in multiple lines. (#4173)
|
||||||
- Bugfix: Fixed the wrong right-click menu showing in the chat input box. (#4177)
|
- Bugfix: Fixed the wrong right-click menu showing in the chat input box. (#4177)
|
||||||
- Bugfix: Fixed popup windows not appearing/minimizing correctly on the Windows taskbar. (#4181)
|
- Bugfix: Fixed popup windows not appearing/minimizing correctly on the Windows taskbar. (#4181)
|
||||||
|
|
|
@ -8,7 +8,7 @@ list(APPEND CMAKE_MODULE_PATH
|
||||||
"${CMAKE_SOURCE_DIR}/cmake/sanitizers-cmake/cmake"
|
"${CMAKE_SOURCE_DIR}/cmake/sanitizers-cmake/cmake"
|
||||||
)
|
)
|
||||||
|
|
||||||
project(chatterino VERSION 2.4.0)
|
project(chatterino VERSION 2.4.1)
|
||||||
|
|
||||||
option(BUILD_APP "Build Chatterino" ON)
|
option(BUILD_APP "Build Chatterino" ON)
|
||||||
option(BUILD_TESTS "Build the tests for Chatterino" OFF)
|
option(BUILD_TESTS "Build the tests for Chatterino" OFF)
|
||||||
|
@ -59,6 +59,13 @@ find_package(Qt${MAJOR_QT_VERSION} REQUIRED
|
||||||
Concurrent
|
Concurrent
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (BUILD_WITH_QT6)
|
||||||
|
find_package(Qt${MAJOR_QT_VERSION} REQUIRED
|
||||||
|
COMPONENTS
|
||||||
|
Core5Compat
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
message(STATUS "Qt version: ${Qt${MAJOR_QT_VERSION}_VERSION}")
|
message(STATUS "Qt version: ${Qt${MAJOR_QT_VERSION}_VERSION}")
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
# If the git binary is found and the git work tree is intact, GIT_RELEASE is worked out using the `git describe` command
|
# If the git binary is found and the git work tree is intact, GIT_RELEASE is worked out using the `git describe` command
|
||||||
# The value of GIT_RELEASE can be overriden by defining the GIT_RELEASE environment variable
|
# The value of GIT_RELEASE can be overriden by defining the GIT_RELEASE environment variable
|
||||||
# GIT_MODIFIED
|
# GIT_MODIFIED
|
||||||
# If the git binary is found and the git work tree is intact, GIT_MODIFIED is worked out by checking if output of `git status --porcelain -z` command is empty
|
# If the git binary is found and the git work tree is intact, GIT_MODIFIED is worked out by checking if output of `git status --porcelain -z` command is empty
|
||||||
# The value of GIT_MODIFIED cannot be overriden
|
# The value of GIT_MODIFIED cannot be overriden
|
||||||
|
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
|
@ -19,67 +19,75 @@ set(GIT_COMMIT "GIT-REPOSITORY-NOT-FOUND")
|
||||||
set(GIT_RELEASE "${PROJECT_VERSION}")
|
set(GIT_RELEASE "${PROJECT_VERSION}")
|
||||||
set(GIT_MODIFIED 0)
|
set(GIT_MODIFIED 0)
|
||||||
|
|
||||||
if (DEFINED ENV{CHATTERINO_SKIP_GIT_GEN})
|
if(DEFINED ENV{CHATTERINO_SKIP_GIT_GEN})
|
||||||
return()
|
return()
|
||||||
endif ()
|
endif()
|
||||||
|
|
||||||
if (GIT_EXECUTABLE)
|
if(GIT_EXECUTABLE)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree
|
COMMAND ${GIT_EXECUTABLE} rev-parse --is-inside-work-tree
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
RESULT_VARIABLE GIT_REPOSITORY_NOT_FOUND
|
RESULT_VARIABLE GIT_REPOSITORY_NOT_FOUND
|
||||||
OUTPUT_QUIET
|
OUTPUT_QUIET
|
||||||
ERROR_QUIET
|
ERROR_QUIET
|
||||||
)
|
)
|
||||||
if (GIT_REPOSITORY_NOT_FOUND)
|
|
||||||
|
if(GIT_REPOSITORY_NOT_FOUND)
|
||||||
set(GIT_REPOSITORY_FOUND 0)
|
set(GIT_REPOSITORY_FOUND 0)
|
||||||
else ()
|
else()
|
||||||
set(GIT_REPOSITORY_FOUND 1)
|
set(GIT_REPOSITORY_FOUND 1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (GIT_REPOSITORY_FOUND)
|
if(GIT_REPOSITORY_FOUND)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_HASH
|
OUTPUT_VARIABLE GIT_HASH
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_COMMIT
|
OUTPUT_VARIABLE GIT_COMMIT
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} describe
|
COMMAND ${GIT_EXECUTABLE} describe
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_RELEASE
|
OUTPUT_VARIABLE GIT_RELEASE
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${GIT_EXECUTABLE} status --porcelain -z
|
COMMAND ${GIT_EXECUTABLE} status --porcelain -z
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_MODIFIED_OUTPUT
|
OUTPUT_VARIABLE GIT_MODIFIED_OUTPUT
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
endif (GIT_REPOSITORY_FOUND)
|
endif(GIT_REPOSITORY_FOUND)
|
||||||
endif (GIT_EXECUTABLE)
|
endif(GIT_EXECUTABLE)
|
||||||
|
|
||||||
|
if(GIT_MODIFIED_OUTPUT)
|
||||||
|
if(DEFINED ENV{CHATTERINO_REQUIRE_CLEAN_GIT})
|
||||||
|
message(STATUS "git status --porcelain -z\n${GIT_MODIFIED_OUTPUT}")
|
||||||
|
message(FATAL_ERROR "Git repository was expected to be clean, but modifications were found!")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (GIT_MODIFIED_OUTPUT)
|
|
||||||
set(GIT_MODIFIED 1)
|
set(GIT_MODIFIED 1)
|
||||||
endif ()
|
endif()
|
||||||
|
|
||||||
if (DEFINED ENV{GIT_HASH})
|
if(DEFINED ENV{GIT_HASH})
|
||||||
set(GIT_HASH "$ENV{GIT_HASH}")
|
set(GIT_HASH "$ENV{GIT_HASH}")
|
||||||
endif ()
|
endif()
|
||||||
if (DEFINED ENV{GIT_COMMIT})
|
|
||||||
|
if(DEFINED ENV{GIT_COMMIT})
|
||||||
set(GIT_COMMIT "$ENV{GIT_COMMIT}")
|
set(GIT_COMMIT "$ENV{GIT_COMMIT}")
|
||||||
endif ()
|
endif()
|
||||||
if (DEFINED ENV{GIT_RELEASE})
|
|
||||||
|
if(DEFINED ENV{GIT_RELEASE})
|
||||||
set(GIT_RELEASE "$ENV{GIT_RELEASE}")
|
set(GIT_RELEASE "$ENV{GIT_RELEASE}")
|
||||||
endif ()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Injected git values: ${GIT_COMMIT} (${GIT_RELEASE}) modified: ${GIT_MODIFIED}")
|
message(STATUS "Injected git values: ${GIT_COMMIT} (${GIT_RELEASE}) modified: ${GIT_MODIFIED}")
|
||||||
|
|
|
@ -32,6 +32,6 @@
|
||||||
<binary>chatterino</binary>
|
<binary>chatterino</binary>
|
||||||
</provides>
|
</provides>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="2.4.0" date="2022-11-28"/>
|
<release version="2.4.1" date="2023-02-18"/>
|
||||||
</releases>
|
</releases>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -643,6 +643,13 @@ if (CHATTERINO_PLUGINS)
|
||||||
target_link_libraries(${LIBRARY_PROJECT} PUBLIC lua)
|
target_link_libraries(${LIBRARY_PROJECT} PUBLIC lua)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (BUILD_WITH_QT6)
|
||||||
|
target_link_libraries(${LIBRARY_PROJECT}
|
||||||
|
PUBLIC
|
||||||
|
Qt${MAJOR_QT_VERSION}::Core5Compat
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (BUILD_WITH_QTKEYCHAIN)
|
if (BUILD_WITH_QTKEYCHAIN)
|
||||||
target_link_libraries(${LIBRARY_PROJECT}
|
target_link_libraries(${LIBRARY_PROJECT}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
|
|
@ -105,7 +105,6 @@
|
||||||
# include <QThreadPool>
|
# include <QThreadPool>
|
||||||
# include <QTime>
|
# include <QTime>
|
||||||
# include <QTimer>
|
# include <QTimer>
|
||||||
# include <QtWidgets/QAction>
|
|
||||||
# include <QtWidgets/QApplication>
|
# include <QtWidgets/QApplication>
|
||||||
# include <QtWidgets/QButtonGroup>
|
# include <QtWidgets/QButtonGroup>
|
||||||
# include <QtWidgets/QDialog>
|
# include <QtWidgets/QDialog>
|
||||||
|
|
|
@ -185,6 +185,38 @@ namespace {
|
||||||
}
|
}
|
||||||
qCDebug(chatterinoCache) << "Deleted" << deletedCount << "files";
|
qCDebug(chatterinoCache) << "Deleted" << deletedCount << "files";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We delete all but the five most recent crashdumps. This strategy may be
|
||||||
|
// improved in the future.
|
||||||
|
void clearCrashes(QDir dir)
|
||||||
|
{
|
||||||
|
// crashpad crashdumps are stored inside the Crashes/report directory
|
||||||
|
if (!dir.cd("reports"))
|
||||||
|
{
|
||||||
|
// no reports directory exists = no files to delete
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir.setNameFilters({"*.dmp"});
|
||||||
|
|
||||||
|
size_t deletedCount = 0;
|
||||||
|
// TODO: use std::views::drop once supported by all compilers
|
||||||
|
size_t filesToSkip = 5;
|
||||||
|
for (auto &&info : dir.entryInfoList(QDir::Files, QDir::Time))
|
||||||
|
{
|
||||||
|
if (filesToSkip > 0)
|
||||||
|
{
|
||||||
|
filesToSkip--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QFile(info.absoluteFilePath()).remove())
|
||||||
|
{
|
||||||
|
deletedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qCDebug(chatterinoApp) << "Deleted" << deletedCount << "crashdumps";
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void runGui(QApplication &a, Paths &paths, Settings &settings)
|
void runGui(QApplication &a, Paths &paths, Settings &settings)
|
||||||
|
@ -215,10 +247,15 @@ void runGui(QApplication &a, Paths &paths, Settings &settings)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear the cache 1 minute after start.
|
// Clear the cache 1 minute after start.
|
||||||
QTimer::singleShot(60 * 1000, [cachePath = paths.cacheDirectory()] {
|
QTimer::singleShot(60 * 1000, [cachePath = paths.cacheDirectory(),
|
||||||
|
crashDirectory = paths.crashdumpDirectory] {
|
||||||
QtConcurrent::run([cachePath]() {
|
QtConcurrent::run([cachePath]() {
|
||||||
clearCache(cachePath);
|
clearCache(cachePath);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QtConcurrent::run([crashDirectory]() {
|
||||||
|
clearCrashes(crashDirectory);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
chatterino::NetworkManager::init();
|
chatterino::NetworkManager::init();
|
||||||
|
|
|
@ -16,7 +16,12 @@ namespace {
|
||||||
QFile file(":/tlds.txt");
|
QFile file(":/tlds.txt");
|
||||||
file.open(QFile::ReadOnly);
|
file.open(QFile::ReadOnly);
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
// Default encoding of QTextStream is already UTF-8, at least in Qt6
|
||||||
|
#else
|
||||||
stream.setCodec("UTF-8");
|
stream.setCodec("UTF-8");
|
||||||
|
#endif
|
||||||
int safetyMax = 20000;
|
int safetyMax = 20000;
|
||||||
|
|
||||||
QSet<QString> set;
|
QSet<QString> set;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
* - 2.4.0-alpha.2
|
* - 2.4.0-alpha.2
|
||||||
* - 2.4.0-alpha
|
* - 2.4.0-alpha
|
||||||
**/
|
**/
|
||||||
#define CHATTERINO_VERSION "2.4.0"
|
#define CHATTERINO_VERSION "2.4.1"
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
# define CHATTERINO_OS "win"
|
# define CHATTERINO_OS "win"
|
||||||
|
|
|
@ -3192,7 +3192,8 @@ QString CommandController::execCommand(const QString &textNoEmoji,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto maxSpaces = std::min(this->maxSpaces_, words.length() - 1);
|
// We have checks to ensure words cannot be empty, so this can never wrap around
|
||||||
|
auto maxSpaces = std::min(this->maxSpaces_, (qsizetype)words.length() - 1);
|
||||||
for (int i = 0; i < maxSpaces; ++i)
|
for (int i = 0; i < maxSpaces; ++i)
|
||||||
{
|
{
|
||||||
commandName += ' ' + words[i + 1];
|
commandName += ' ' + words[i + 1];
|
||||||
|
|
|
@ -71,7 +71,7 @@ private:
|
||||||
|
|
||||||
// User-created commands
|
// User-created commands
|
||||||
QMap<QString, Command> userCommands_;
|
QMap<QString, Command> userCommands_;
|
||||||
int maxSpaces_ = 0;
|
qsizetype maxSpaces_ = 0;
|
||||||
|
|
||||||
std::shared_ptr<pajlada::Settings::SettingManager> sm_;
|
std::shared_ptr<pajlada::Settings::SettingManager> sm_;
|
||||||
// Because the setting manager is not initialized until the initialize
|
// Because the setting manager is not initialized until the initialize
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#define MINIAUDIO_IMPLEMENTATION
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
#include <miniaudio.h>
|
#include <miniaudio.h>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "providers/bttv/liveupdates/BttvLiveUpdateSubscription.hpp"
|
#include "providers/bttv/liveupdates/BttvLiveUpdateSubscription.hpp"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
|
@ -94,7 +94,8 @@ void IrcServer::initializeConnectionSignals(IrcConnection *connection,
|
||||||
|
|
||||||
QObject::connect(connection, &Communi::IrcConnection::nickNameRequired,
|
QObject::connect(connection, &Communi::IrcConnection::nickNameRequired,
|
||||||
this, [](const QString &reserved, QString *result) {
|
this, [](const QString &reserved, QString *result) {
|
||||||
*result = reserved + (std::rand() % 100);
|
*result = QString("%1%2").arg(
|
||||||
|
reserved, QString::number(std::rand() % 100));
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(connection, &Communi::IrcConnection::noticeMessageReceived,
|
QObject::connect(connection, &Communi::IrcConnection::noticeMessageReceived,
|
||||||
|
|
|
@ -810,7 +810,7 @@ void IrcMessageHandler::handleWhisperMessage(Communi::IrcMessage *message)
|
||||||
|
|
||||||
getApp()->twitch->lastUserThatWhisperedMe.set(builder.userName);
|
getApp()->twitch->lastUserThatWhisperedMe.set(builder.userName);
|
||||||
|
|
||||||
if (_message->flags.has(MessageFlag::Highlighted))
|
if (_message->flags.has(MessageFlag::ShowInMentions))
|
||||||
{
|
{
|
||||||
getApp()->twitch->mentionsChannel->addMessage(_message);
|
getApp()->twitch->mentionsChannel->addMessage(_message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,7 +325,7 @@ std::shared_ptr<Channel> TwitchIrcServer::getChannelOrEmptyByID(
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (twitchChannel->roomId() == channelId &&
|
if (twitchChannel->roomId() == channelId &&
|
||||||
twitchChannel->getName().splitRef(":").size() < 3)
|
twitchChannel->getName().count(':') < 2)
|
||||||
{
|
{
|
||||||
return twitchChannel;
|
return twitchChannel;
|
||||||
}
|
}
|
||||||
|
|
|
@ -821,14 +821,14 @@ void TwitchMessageBuilder::runIgnoreReplaces(
|
||||||
};
|
};
|
||||||
|
|
||||||
auto addReplEmotes = [&twitchEmotes](const IgnorePhrase &phrase,
|
auto addReplEmotes = [&twitchEmotes](const IgnorePhrase &phrase,
|
||||||
const QStringRef &midrepl,
|
const auto &midrepl,
|
||||||
int startIndex) mutable {
|
int startIndex) mutable {
|
||||||
if (!phrase.containsEmote())
|
if (!phrase.containsEmote())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QStringRef> words = midrepl.split(' ');
|
auto words = midrepl.split(' ');
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for (const auto &word : words)
|
for (const auto &word : words)
|
||||||
{
|
{
|
||||||
|
@ -843,7 +843,7 @@ void TwitchMessageBuilder::runIgnoreReplaces(
|
||||||
}
|
}
|
||||||
twitchEmotes.push_back(TwitchEmoteOccurrence{
|
twitchEmotes.push_back(TwitchEmoteOccurrence{
|
||||||
startIndex + pos,
|
startIndex + pos,
|
||||||
startIndex + pos + emote.first.string.length(),
|
startIndex + pos + (int)emote.first.string.length(),
|
||||||
emote.second,
|
emote.second,
|
||||||
emote.first,
|
emote.first,
|
||||||
});
|
});
|
||||||
|
@ -904,8 +904,13 @@ void TwitchMessageBuilder::runIgnoreReplaces(
|
||||||
|
|
||||||
shiftIndicesAfter(from + len, midsize - len);
|
shiftIndicesAfter(from + len, midsize - len);
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
|
auto midExtendedRef =
|
||||||
|
QStringView{this->originalMessage_}.mid(pos1, pos2 - pos1);
|
||||||
|
#else
|
||||||
auto midExtendedRef =
|
auto midExtendedRef =
|
||||||
this->originalMessage_.midRef(pos1, pos2 - pos1);
|
this->originalMessage_.midRef(pos1, pos2 - pos1);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (auto &tup : vret)
|
for (auto &tup : vret)
|
||||||
{
|
{
|
||||||
|
@ -969,8 +974,13 @@ void TwitchMessageBuilder::runIgnoreReplaces(
|
||||||
|
|
||||||
shiftIndicesAfter(from + len, replacesize - len);
|
shiftIndicesAfter(from + len, replacesize - len);
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
|
auto midExtendedRef =
|
||||||
|
QStringView{this->originalMessage_}.mid(pos1, pos2 - pos1);
|
||||||
|
#else
|
||||||
auto midExtendedRef =
|
auto midExtendedRef =
|
||||||
this->originalMessage_.midRef(pos1, pos2 - pos1);
|
this->originalMessage_.midRef(pos1, pos2 - pos1);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (auto &tup : vret)
|
for (auto &tup : vret)
|
||||||
{
|
{
|
||||||
|
|
|
@ -174,6 +174,12 @@ QString localizeNumbers(unsigned int number)
|
||||||
return locale.toString(number);
|
return locale.toString(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString localizeNumbers(qsizetype number)
|
||||||
|
{
|
||||||
|
QLocale locale;
|
||||||
|
return locale.toString(number);
|
||||||
|
}
|
||||||
|
|
||||||
QString kFormatNumbers(const int &number)
|
QString kFormatNumbers(const int &number)
|
||||||
{
|
{
|
||||||
return QString("%1K").arg(number / 1000);
|
return QString("%1K").arg(number / 1000);
|
||||||
|
|
|
@ -74,6 +74,7 @@ QString shortenString(const QString &str, unsigned maxWidth = 50);
|
||||||
|
|
||||||
QString localizeNumbers(const int &number);
|
QString localizeNumbers(const int &number);
|
||||||
QString localizeNumbers(unsigned int number);
|
QString localizeNumbers(unsigned int number);
|
||||||
|
QString localizeNumbers(qsizetype number);
|
||||||
|
|
||||||
QString kFormatNumbers(const int &number);
|
QString kFormatNumbers(const int &number);
|
||||||
|
|
||||||
|
|
|
@ -641,8 +641,8 @@ void Notebook::performLayout(bool animated)
|
||||||
bool isLastColumn = col == columnCount - 1;
|
bool isLastColumn = col == columnCount - 1;
|
||||||
auto largestWidth = 0;
|
auto largestWidth = 0;
|
||||||
int tabStart = col * tabsPerColumn;
|
int tabStart = col * tabsPerColumn;
|
||||||
int tabEnd =
|
int tabEnd = std::min((col + 1) * tabsPerColumn,
|
||||||
std::min((col + 1) * tabsPerColumn, this->items_.size());
|
(int)this->items_.size());
|
||||||
|
|
||||||
for (int i = tabStart; i < tabEnd; i++)
|
for (int i = tabStart; i < tabEnd; i++)
|
||||||
{
|
{
|
||||||
|
@ -743,8 +743,8 @@ void Notebook::performLayout(bool animated)
|
||||||
bool isLastColumn = col == columnCount - 1;
|
bool isLastColumn = col == columnCount - 1;
|
||||||
auto largestWidth = 0;
|
auto largestWidth = 0;
|
||||||
int tabStart = col * tabsPerColumn;
|
int tabStart = col * tabsPerColumn;
|
||||||
int tabEnd =
|
int tabEnd = std::min((col + 1) * tabsPerColumn,
|
||||||
std::min((col + 1) * tabsPerColumn, this->items_.size());
|
(int)this->items_.size());
|
||||||
|
|
||||||
for (int i = tabStart; i < tabEnd; i++)
|
for (int i = tabStart; i < tabEnd; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "widgets/settingspages/PluginsPage.hpp"
|
#include "widgets/settingspages/PluginsPage.hpp"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QFile>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
|
@ -419,16 +419,28 @@ UserInfoPopup::UserInfoPopup(bool closeAutomatically, QWidget *parent,
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(mod.getElement(), &Button::leftClicked, [this] {
|
QObject::connect(mod.getElement(), &Button::leftClicked, [this] {
|
||||||
this->underlyingChannel_->sendMessage("/mod " + this->userName_);
|
QString value = "/mod " + this->userName_;
|
||||||
|
value = getApp()->commands->execCommand(
|
||||||
|
value, this->underlyingChannel_, false);
|
||||||
|
this->underlyingChannel_->sendMessage(value);
|
||||||
});
|
});
|
||||||
QObject::connect(unmod.getElement(), &Button::leftClicked, [this] {
|
QObject::connect(unmod.getElement(), &Button::leftClicked, [this] {
|
||||||
this->underlyingChannel_->sendMessage("/unmod " + this->userName_);
|
QString value = "/unmod " + this->userName_;
|
||||||
|
value = getApp()->commands->execCommand(
|
||||||
|
value, this->underlyingChannel_, false);
|
||||||
|
this->underlyingChannel_->sendMessage(value);
|
||||||
});
|
});
|
||||||
QObject::connect(vip.getElement(), &Button::leftClicked, [this] {
|
QObject::connect(vip.getElement(), &Button::leftClicked, [this] {
|
||||||
this->underlyingChannel_->sendMessage("/vip " + this->userName_);
|
QString value = "/vip " + this->userName_;
|
||||||
|
value = getApp()->commands->execCommand(
|
||||||
|
value, this->underlyingChannel_, false);
|
||||||
|
this->underlyingChannel_->sendMessage(value);
|
||||||
});
|
});
|
||||||
QObject::connect(unvip.getElement(), &Button::leftClicked, [this] {
|
QObject::connect(unvip.getElement(), &Button::leftClicked, [this] {
|
||||||
this->underlyingChannel_->sendMessage("/unvip " + this->userName_);
|
QString value = "/unvip " + this->userName_;
|
||||||
|
value = getApp()->commands->execCommand(
|
||||||
|
value, this->underlyingChannel_, false);
|
||||||
|
this->underlyingChannel_->sendMessage(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// userstate
|
// userstate
|
||||||
|
|
|
@ -62,7 +62,11 @@ QString ResizingTextEdit::textUnderCursor(bool *hadSpace) const
|
||||||
|
|
||||||
auto textUpToCursor = currentText.left(tc.selectionStart());
|
auto textUpToCursor = currentText.left(tc.selectionStart());
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
|
auto words = QStringView{textUpToCursor}.split(' ');
|
||||||
|
#else
|
||||||
auto words = textUpToCursor.splitRef(' ');
|
auto words = textUpToCursor.splitRef(' ');
|
||||||
|
#endif
|
||||||
if (words.size() == 0)
|
if (words.size() == 0)
|
||||||
{
|
{
|
||||||
return QString();
|
return QString();
|
||||||
|
|
|
@ -54,7 +54,7 @@ void SettingsDialogTab::paintEvent(QPaintEvent *)
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
|
||||||
QStyleOption opt;
|
QStyleOption opt;
|
||||||
opt.init(this);
|
opt.initFrom(this);
|
||||||
|
|
||||||
this->style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
|
this->style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "widgets/BasePopup.hpp"
|
#include "widgets/BasePopup.hpp"
|
||||||
#include "widgets/helper/SignalLabel.hpp"
|
#include "widgets/helper/SignalLabel.hpp"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
@ -151,7 +152,11 @@ AboutPage::AboutPage()
|
||||||
contributorsFile.open(QFile::ReadOnly);
|
contributorsFile.open(QFile::ReadOnly);
|
||||||
|
|
||||||
QTextStream stream(&contributorsFile);
|
QTextStream stream(&contributorsFile);
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
// Default encoding of QTextStream is already UTF-8
|
||||||
|
#else
|
||||||
stream.setCodec("UTF-8");
|
stream.setCodec("UTF-8");
|
||||||
|
#endif
|
||||||
|
|
||||||
QString line;
|
QString line;
|
||||||
|
|
||||||
|
|
|
@ -112,35 +112,36 @@ ModerationPage::ModerationPage()
|
||||||
// Show how big (size-wise) the logs are
|
// Show how big (size-wise) the logs are
|
||||||
auto logsPathSizeLabel = logs.emplace<QLabel>();
|
auto logsPathSizeLabel = logs.emplace<QLabel>();
|
||||||
logsPathSizeLabel->setText(QtConcurrent::run([] {
|
logsPathSizeLabel->setText(QtConcurrent::run([] {
|
||||||
return fetchLogDirectorySize();
|
return fetchLogDirectorySize();
|
||||||
}));
|
}).result());
|
||||||
|
|
||||||
// Select event
|
// Select event
|
||||||
QObject::connect(selectDir.getElement(), &QPushButton::clicked, this,
|
QObject::connect(
|
||||||
[this, logsPathSizeLabel]() mutable {
|
selectDir.getElement(), &QPushButton::clicked, this,
|
||||||
auto dirName =
|
[this, logsPathSizeLabel]() mutable {
|
||||||
QFileDialog::getExistingDirectory(this);
|
auto dirName = QFileDialog::getExistingDirectory(this);
|
||||||
|
|
||||||
getSettings()->logPath = dirName;
|
getSettings()->logPath = dirName;
|
||||||
|
|
||||||
// Refresh: Show how big (size-wise) the logs are
|
// Refresh: Show how big (size-wise) the logs are
|
||||||
logsPathSizeLabel->setText(QtConcurrent::run([] {
|
logsPathSizeLabel->setText(QtConcurrent::run([] {
|
||||||
return fetchLogDirectorySize();
|
return fetchLogDirectorySize();
|
||||||
}));
|
}).result());
|
||||||
});
|
});
|
||||||
|
|
||||||
buttons->addSpacing(16);
|
buttons->addSpacing(16);
|
||||||
|
|
||||||
// Reset custom logpath
|
// Reset custom logpath
|
||||||
QObject::connect(resetDir.getElement(), &QPushButton::clicked, this,
|
QObject::connect(
|
||||||
[logsPathSizeLabel]() mutable {
|
resetDir.getElement(), &QPushButton::clicked, this,
|
||||||
getSettings()->logPath = "";
|
[logsPathSizeLabel]() mutable {
|
||||||
|
getSettings()->logPath = "";
|
||||||
|
|
||||||
// Refresh: Show how big (size-wise) the logs are
|
// Refresh: Show how big (size-wise) the logs are
|
||||||
logsPathSizeLabel->setText(QtConcurrent::run([] {
|
logsPathSizeLabel->setText(QtConcurrent::run([] {
|
||||||
return fetchLogDirectorySize();
|
return fetchLogDirectorySize();
|
||||||
}));
|
}).result());
|
||||||
});
|
});
|
||||||
|
|
||||||
QCheckBox *onlyLogListedChannels =
|
QCheckBox *onlyLogListedChannels =
|
||||||
this->createCheckBox("Only log channels listed below",
|
this->createCheckBox("Only log channels listed below",
|
||||||
|
|
|
@ -699,7 +699,7 @@ void SplitInput::updateCompletionPopup()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = clamp(position, 0, text.length() - 1); i >= 0; i--)
|
for (int i = clamp(position, 0, (int)text.length() - 1); i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (text[i] == ' ')
|
if (text[i] == ' ')
|
||||||
{
|
{
|
||||||
|
@ -766,7 +766,7 @@ void SplitInput::showCompletionPopup(const QString &text, bool emoteCompletion)
|
||||||
popup->updateUsers(text, this->split_->getChannel());
|
popup->updateUsers(text, this->split_->getChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pos = this->mapToGlobal({0, 0}) - QPoint(0, popup->height()) +
|
auto pos = this->mapToGlobal(QPoint{0, 0}) - QPoint(0, popup->height()) +
|
||||||
QPoint((this->width() - popup->width()) / 2, 0);
|
QPoint((this->width() - popup->width()) / 2, 0);
|
||||||
|
|
||||||
popup->move(pos);
|
popup->move(pos);
|
||||||
|
@ -789,7 +789,7 @@ void SplitInput::insertCompletionText(const QString &input_) const
|
||||||
auto text = edit.toPlainText();
|
auto text = edit.toPlainText();
|
||||||
auto position = edit.textCursor().position() - 1;
|
auto position = edit.textCursor().position() - 1;
|
||||||
|
|
||||||
for (int i = clamp(position, 0, text.length() - 1); i >= 0; i--)
|
for (int i = clamp(position, 0, (int)text.length() - 1); i >= 0; i--)
|
||||||
{
|
{
|
||||||
bool done = false;
|
bool done = false;
|
||||||
if (text[i] == ':')
|
if (text[i] == ':')
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Application.hpp"
|
#include "Application.hpp"
|
||||||
#include "BaseSettings.hpp"
|
#include "BaseSettings.hpp"
|
||||||
#include "controllers/accounts/AccountController.hpp"
|
#include "controllers/accounts/AccountController.hpp"
|
||||||
|
#include "controllers/highlights/HighlightPhrase.hpp"
|
||||||
#include "messages/MessageBuilder.hpp" // for MessageParseArgs
|
#include "messages/MessageBuilder.hpp" // for MessageParseArgs
|
||||||
#include "mocks/UserData.hpp"
|
#include "mocks/UserData.hpp"
|
||||||
#include "providers/twitch/api/Helix.hpp"
|
#include "providers/twitch/api/Helix.hpp"
|
||||||
|
@ -774,6 +775,56 @@ TEST_F(HighlightControllerTest, A)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// TEST CASE: Whispers that do not hit a highlight phrase should not be added to /mentions
|
||||||
|
{
|
||||||
|
// input
|
||||||
|
.args =
|
||||||
|
MessageParseArgs{
|
||||||
|
.isReceivedWhisper = true,
|
||||||
|
},
|
||||||
|
.senderName = "forsen",
|
||||||
|
.originalMessage = "Hello NymN!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
.state = true, // state
|
||||||
|
.result =
|
||||||
|
{
|
||||||
|
false, // alert
|
||||||
|
false, // playsound
|
||||||
|
boost::none, // custom sound url
|
||||||
|
std::make_shared<QColor>(
|
||||||
|
HighlightPhrase::
|
||||||
|
FALLBACK_HIGHLIGHT_COLOR), // color
|
||||||
|
false, // showInMentions
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// TEST CASE: Whispers that do hit a highlight phrase should be added to /mentions
|
||||||
|
{
|
||||||
|
// input
|
||||||
|
.args =
|
||||||
|
MessageParseArgs{
|
||||||
|
.isReceivedWhisper = true,
|
||||||
|
},
|
||||||
|
.senderName = "forsen",
|
||||||
|
.originalMessage = "!testmanxd",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
.state = true, // state
|
||||||
|
.result =
|
||||||
|
{
|
||||||
|
true, // alert
|
||||||
|
true, // playsound
|
||||||
|
boost::none, // custom sound url
|
||||||
|
std::make_shared<QColor>("#7f7f3f49"), // color
|
||||||
|
true, // showInMentions
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &[input, expected] : tests)
|
for (const auto &[input, expected] : tests)
|
||||||
|
|
Loading…
Reference in a new issue