diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index f884d69f1..7c174f62a 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -115,37 +115,81 @@ jobs: echo "When CI is done, the above patch will be uploaded as 'code-style.diff' to https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/ ." exit 1 - sanitizer-tests: - runs-on: ubuntu-22.04 +# sanitizer-tests-ubuntu: +# runs-on: ubuntu-22.04 +# needs: [ what-to-make ] +# if: ${{ needs.what-to-make.outputs.make-tests == 'true' }} +# env: +# NODE_PATH: /usr/lib/nodejs:/usr/share/nodejs +# steps: +# - name: Show Configuration +# run: | +# echo '${{ toJSON(needs) }}' +# echo '${{ toJSON(runner) }}' +# cat /etc/os-release +# - name: Get Dependencies +# run: | +# set -ex +# sudo apt-get update +# sudo apt-get install -y --no-install-recommends \ +# ca-certificates \ +# clang \ +# cmake \ +# gettext \ +# libcurl4-openssl-dev \ +# libdeflate-dev \ +# libevent-dev \ +# libfmt-dev \ +# libminiupnpc-dev \ +# libnatpmp-dev \ +# libpsl-dev \ +# libssl-dev \ +# ninja-build \ +# npm +# - name: Get Source +# uses: actions/checkout@v4 +# with: +# submodules: recursive +# path: src +# - name: Configure +# run: | +# cmake \ +# -S src \ +# -B obj \ +# -G Ninja \ +# -DCMAKE_BUILD_TYPE=Debug \ +# -DCMAKE_CXX_COMPILER='clang++' \ +# -DCMAKE_CXX_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \ +# -DCMAKE_C_COMPILER='clang' \ +# -DCMAKE_C_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \ +# -DCMAKE_INSTALL_PREFIX=pfx \ +# -DENABLE_CLI=OFF \ +# -DENABLE_DAEMON=OFF \ +# -DENABLE_GTK=OFF \ +# -DENABLE_MAC=OFF \ +# -DENABLE_QT=OFF \ +# -DENABLE_TESTS=ON \ +# -DENABLE_UTILS=ON \ +# -DREBUILD_WEB=OFF \ +# -DRUN_CLANG_TIDY=OFF +# - name: Make +# run: cmake --build obj --config Debug --target libtransmission-test transmission-show +# - name: Test with sanitizers +# run: cmake -E chdir obj ctest -j $(nproc) --build-config Debug --output-on-failure + + sanitizer-tests-macos: + runs-on: macos-14 needs: [ what-to-make ] if: ${{ needs.what-to-make.outputs.make-tests == 'true' }} - env: - NODE_PATH: /usr/lib/nodejs:/usr/share/nodejs steps: - name: Show Configuration run: | echo '${{ toJSON(needs) }}' echo '${{ toJSON(runner) }}' - cat /etc/os-release + sw_vers - name: Get Dependencies run: | - set -ex - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - ca-certificates \ - clang \ - cmake \ - gettext \ - libcurl4-openssl-dev \ - libdeflate-dev \ - libevent-dev \ - libfmt-dev \ - libminiupnpc-dev \ - libnatpmp-dev \ - libpsl-dev \ - libssl-dev \ - ninja-build \ - npm + brew install cmake gettext libdeflate libevent libpsl miniupnpc ninja node pkg-config - name: Get Source uses: actions/checkout@v4 with: @@ -158,10 +202,8 @@ jobs: -B obj \ -G Ninja \ -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_CXX_COMPILER='clang++' \ - -DCMAKE_CXX_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \ - -DCMAKE_C_COMPILER='clang' \ - -DCMAKE_C_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,leak,undefined' \ + -DCMAKE_CXX_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,undefined' \ + -DCMAKE_C_FLAGS='-gdwarf-4 -fno-omit-frame-pointer -fsanitize=address,undefined' \ -DCMAKE_INSTALL_PREFIX=pfx \ -DENABLE_CLI=OFF \ -DENABLE_DAEMON=OFF \ diff --git a/AUTHORS b/AUTHORS index 78a8e93a5..46a41cf77 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,7 +11,6 @@ Contributor Team Dmitry Serov (@DevilDimon) (macOS client) Dzmitry Neviadomski (@nevack) (macOS client) FX Coudert (@fxcoudert) (macOS client) - Gary Elshaw (@GaryElshaw) John Clay (@JohnClay) SweetP Pro (@sweetppro) (macOS client) Yat Ho (@tearfur) (libtransmission) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01cabfe99..93270cb92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -632,7 +632,6 @@ else() -Wextra -Wcast-align -Wduplicated-cond - -Wexit-time-destructors -Wextra-semi -Wextra-semi-stmt -Wextra-tokens diff --git a/Transmission.xcodeproj/project.pbxproj b/Transmission.xcodeproj/project.pbxproj index f0503bcbf..3282fc02d 100644 --- a/Transmission.xcodeproj/project.pbxproj +++ b/Transmission.xcodeproj/project.pbxproj @@ -452,6 +452,7 @@ ED8A16402735A8AA000D61F9 /* peer-mgr-active-requests.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */; }; ED8A16412735A8AA000D61F9 /* peer-mgr-wishlist.h in Headers */ = {isa = PBXBuildFile; fileRef = ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */; }; ED8A16422735A8AA000D61F9 /* peer-mgr-wishlist.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */; }; + ED9862972B979AA2002F3035 /* Utils.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED9862962B979AA2002F3035 /* Utils.mm */; }; EDBAAC8C29E486BC00D9495F /* global-ip-cache.h in Headers */ = {isa = PBXBuildFile; fileRef = EDBAAC8B29E486BC00D9495F /* global-ip-cache.h */; }; EDBAAC8E29E486C200D9495F /* global-ip-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = EDBAAC8D29E486C200D9495F /* global-ip-cache.cc */; }; EDBDFA9E25AFCCA60093D9C1 /* evutil_time.c in Sources */ = {isa = PBXBuildFile; fileRef = EDBDFA9D25AFCCA60093D9C1 /* evutil_time.c */; }; @@ -1366,6 +1367,8 @@ ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-active-requests.cc"; sourceTree = ""; }; ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = "peer-mgr-wishlist.h"; sourceTree = ""; }; ED8A163E2735A8AA000D61F9 /* peer-mgr-wishlist.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-wishlist.cc"; sourceTree = ""; }; + ED9862952B979AA2002F3035 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = ""; }; + ED9862962B979AA2002F3035 /* Utils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Utils.mm; sourceTree = ""; }; EDBAAC8B29E486BC00D9495F /* global-ip-cache.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = "global-ip-cache.h"; sourceTree = ""; }; EDBAAC8D29E486C200D9495F /* global-ip-cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "global-ip-cache.cc"; sourceTree = ""; }; EDBDFA9D25AFCCA60093D9C1 /* evutil_time.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = evutil_time.c; sourceTree = ""; }; @@ -1664,6 +1667,8 @@ A222EA7A0E6C32C4009FB003 /* BlocklistScheduler.mm */, ED86936D2ADAE34D00342B1A /* DefaultAppHelper.h */, ED86936E2ADAE34D00342B1A /* DefaultAppHelper.mm */, + ED9862952B979AA2002F3035 /* Utils.h */, + ED9862962B979AA2002F3035 /* Utils.mm */, A2AB883916A399A6008FAD50 /* VDKQueue */, ); name = Sources; @@ -3274,6 +3279,7 @@ A209EB9D1142E59A002B02D1 /* InfoPeersViewController.mm in Sources */, A209EBCE1142F2B4002B02D1 /* InfoFileViewController.mm in Sources */, A209EBF91142FEEE002B02D1 /* InfoOptionsViewController.mm in Sources */, + ED9862972B979AA2002F3035 /* Utils.mm in Sources */, A21F15AC11729A8B00CF5A9C /* AddMagnetWindowController.mm in Sources */, A2661D6112D0E8D9004F69D5 /* FilterBarView.mm in Sources */, A2F7CF5F13035FFD0016FF10 /* URLSheetWindowController.mm in Sources */, @@ -3930,6 +3936,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LIBRARY = "libc++"; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "third-party/dht", @@ -4184,6 +4191,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LIBRARY = "libc++"; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "third-party/dht", @@ -4359,6 +4367,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_STRICT_PROTOTYPES = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GENERATE_MASTER_OBJECT_FILE = YES; PRODUCT_NAME = dht; @@ -4369,6 +4378,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_STRICT_PROTOTYPES = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GENERATE_MASTER_OBJECT_FILE = YES; PRODUCT_NAME = dht; @@ -4379,6 +4389,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_STRICT_PROTOTYPES = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GENERATE_MASTER_OBJECT_FILE = YES; PRODUCT_NAME = dht; @@ -4513,6 +4524,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LIBRARY = "libc++"; + GCC_WARN_64_TO_32_BIT_CONVERSION = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "third-party/dht", diff --git a/libtransmission/favicon-cache.h b/libtransmission/favicon-cache.h index 9e65f9fcd..c15ea1b63 100644 --- a/libtransmission/favicon-cache.h +++ b/libtransmission/favicon-cache.h @@ -44,7 +44,7 @@ public: return iter != std::end(icons_) ? &iter->second : nullptr; } - void load( + void load( // std::string_view url_in, IconFunc callback = [](Icon const&) { /*default callback is a no-op */ }) { diff --git a/macosx/BadgeView.mm b/macosx/BadgeView.mm index 81b841c08..9841102c9 100644 --- a/macosx/BadgeView.mm +++ b/macosx/BadgeView.mm @@ -5,6 +5,7 @@ #import "BadgeView.h" #import "NSStringAdditions.h" #import "NSImageAdditions.h" +#import "Utils.h" static CGFloat const kBetweenPadding = 2.0; static NSImage* kWhiteUpArrow = [[NSImage imageNamed:@"UpArrowTemplate"] imageWithColor:NSColor.whiteColor]; @@ -61,7 +62,7 @@ typedef NS_ENUM(NSInteger, ArrowDirection) { - (BOOL)setRatesWithDownload:(CGFloat)downloadRate upload:(CGFloat)uploadRate { //only needs update if the badges were displayed or are displayed now - if (self.fDownloadRate == downloadRate && self.fUploadRate == uploadRate) + if (isSpeedEqual(self.fDownloadRate, downloadRate) && isSpeedEqual(self.fUploadRate, uploadRate)) { return NO; } diff --git a/macosx/CMakeLists.txt b/macosx/CMakeLists.txt index 9ef277835..2e04f2ab1 100644 --- a/macosx/CMakeLists.txt +++ b/macosx/CMakeLists.txt @@ -191,6 +191,8 @@ target_sources(${TR_NAME}-mac TrackerTableView.mm URLSheetWindowController.h URLSheetWindowController.mm + Utils.h + Utils.mm WebSeedTableView.h WebSeedTableView.mm) diff --git a/macosx/InfoOptionsViewController.mm b/macosx/InfoOptionsViewController.mm index 497f35b95..56986b9c2 100644 --- a/macosx/InfoOptionsViewController.mm +++ b/macosx/InfoOptionsViewController.mm @@ -5,6 +5,7 @@ #import "InfoOptionsViewController.h" #import "NSStringAdditions.h" #import "Torrent.h" +#import "Utils.h" typedef NS_ENUM(NSInteger, OptionPopupType) { OptionPopupTypeGlobal = 0, @@ -295,7 +296,7 @@ static CGFloat const kStackViewSpacing = 8.0; checkRatio = kInvalidValue; } - if (!multipleRatioLimits && ratioLimit != torrent.ratioLimit) + if (!multipleRatioLimits && isRatioEqual(ratioLimit, torrent.ratioLimit)) { multipleRatioLimits = YES; } diff --git a/macosx/InfoWindowController.mm b/macosx/InfoWindowController.mm index c6b102a76..bc056bf24 100644 --- a/macosx/InfoWindowController.mm +++ b/macosx/InfoWindowController.mm @@ -351,9 +351,9 @@ typedef NS_ENUM(NSUInteger, TabTag) { viewRect = [self.fOptionsViewController viewRect]; } - CGFloat const difference = NSHeight(viewRect) - oldHeight; - windowRect.origin.y -= difference; - windowRect.size.height += difference; + CGFloat const viewHeightDifference = NSHeight(viewRect) - oldHeight; + windowRect.origin.y -= viewHeightDifference; + windowRect.size.height += viewHeightDifference; windowRect.size.width = MAX(NSWidth(windowRect), minWindowWidth); if ([self.fViewController respondsToSelector:@selector(saveViewSize)]) //a little bit hacky, but avoids requiring an extra method @@ -363,11 +363,11 @@ typedef NS_ENUM(NSUInteger, TabTag) { CGFloat const screenHeight = NSHeight(window.screen.visibleFrame); if (NSHeight(windowRect) > screenHeight) { - CGFloat const difference = screenHeight - NSHeight(windowRect); - windowRect.origin.y -= difference; - windowRect.size.height += difference; + CGFloat const windowHeightDifference = screenHeight - NSHeight(windowRect); + windowRect.origin.y -= windowHeightDifference; + windowRect.size.height += windowHeightDifference; - viewRect.size.height += difference; + viewRect.size.height += windowHeightDifference; } } diff --git a/macosx/PortChecker.mm b/macosx/PortChecker.mm index 3184ccb9f..31e1ac6d5 100644 --- a/macosx/PortChecker.mm +++ b/macosx/PortChecker.mm @@ -72,7 +72,7 @@ static NSTimeInterval const kCheckFireInterval = 3.0; timeoutInterval:15.0]; _fTask = [_fSession dataTaskWithRequest:portProbeRequest - completionHandler:^(NSData* _Nullable data, NSURLResponse* _Nullable response, NSError* _Nullable error) { + completionHandler:^(NSData* _Nullable data, NSURLResponse* _Nullable, NSError* _Nullable error) { if (error) { NSLog(@"Unable to get port status: connection failed (%@)", error.localizedDescription); diff --git a/macosx/StatusBarController.mm b/macosx/StatusBarController.mm index 9d16d66c2..2102e58a3 100644 --- a/macosx/StatusBarController.mm +++ b/macosx/StatusBarController.mm @@ -4,6 +4,7 @@ #import "StatusBarController.h" #import "NSStringAdditions.h" +#import "Utils.h" typedef NSString* StatusRatioType NS_TYPED_EXTENSIBLE_ENUM; @@ -77,13 +78,13 @@ typedef NS_ENUM(NSUInteger, StatusTag) { - (void)updateWithDownload:(CGFloat)dlRate upload:(CGFloat)ulRate { //set rates - if (dlRate != self.fPreviousDownloadRate) + if (!isSpeedEqual(self.fPreviousDownloadRate, dlRate)) { self.fTotalDLField.stringValue = [NSString stringForSpeed:dlRate]; self.fPreviousDownloadRate = dlRate; } - if (ulRate != self.fPreviousUploadRate) + if (!isSpeedEqual(self.fPreviousUploadRate, ulRate)) { self.fTotalULField.stringValue = [NSString stringForSpeed:ulRate]; self.fPreviousUploadRate = ulRate; diff --git a/macosx/TorrentTableView.mm b/macosx/TorrentTableView.mm index 54af6cc07..44cb140cb 100644 --- a/macosx/TorrentTableView.mm +++ b/macosx/TorrentTableView.mm @@ -125,7 +125,7 @@ static NSTimeInterval const kToggleProgressSeconds = 0.175; NSIndexSet* fullIndexSet = [NSIndexSet indexSetWithIndexesInRange:fullRange]; NSMutableIndexSet* visibleIndexSet = [[NSMutableIndexSet alloc] init]; - [fullIndexSet enumerateIndexesUsingBlock:^(NSUInteger row, BOOL* stop) { + [fullIndexSet enumerateIndexesUsingBlock:^(NSUInteger row, BOOL*) { id rowView = [self rowViewAtRow:row makeIfNecessary:NO]; if ([rowView isGroupRowStyle]) { @@ -151,7 +151,7 @@ static NSTimeInterval const kToggleProgressSeconds = 0.175; //redraw fControlButton BOOL minimal = [self.fDefaults boolForKey:@"SmallView"]; - [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger row, BOOL* stop) { + [rowIndexes enumerateIndexesUsingBlock:^(NSUInteger row, BOOL*) { id rowView = [self rowViewAtRow:row makeIfNecessary:NO]; if (![rowView isGroupRowStyle]) { diff --git a/macosx/Utils.h b/macosx/Utils.h new file mode 100644 index 000000000..311054c8c --- /dev/null +++ b/macosx/Utils.h @@ -0,0 +1,8 @@ +// This file Copyright © Transmission authors and contributors. +// It may be used under the MIT (SPDX: MIT) license. +// License text can be found in the licenses/ folder. + +#import + +bool isSpeedEqual(CGFloat old_speed, CGFloat new_speed); +bool isRatioEqual(CGFloat old_ratio, CGFloat new_ratio); diff --git a/macosx/Utils.mm b/macosx/Utils.mm new file mode 100644 index 000000000..b7130ca48 --- /dev/null +++ b/macosx/Utils.mm @@ -0,0 +1,19 @@ +// This file Copyright © Transmission authors and contributors. +// It may be used under the MIT (SPDX: MIT) license. +// License text can be found in the licenses/ folder. + +#include + +#import "Utils.h" + +bool isSpeedEqual(CGFloat old_speed, CGFloat new_speed) +{ + static CGFloat constexpr kSpeedCompareEps = 0.1 / 2; + return std::abs(new_speed - old_speed) < kSpeedCompareEps; +} + +bool isRatioEqual(CGFloat old_ratio, CGFloat new_ratio) +{ + static CGFloat constexpr kRatioCompareEps = 0.01 / 2; + return std::abs(new_ratio - old_ratio) < kRatioCompareEps; +} diff --git a/qt/RpcClient.cc b/qt/RpcClient.cc index 46f8d87d2..bb0be68db 100644 --- a/qt/RpcClient.cc +++ b/qt/RpcClient.cc @@ -130,8 +130,7 @@ void RpcClient::sendNetworkRequest(TrVariantPtr req, QFutureInterfacerawHeaderList()) { diff --git a/tests/libtransmission/dht-test.cc b/tests/libtransmission/dht-test.cc index 7b4c452c6..f723fad8e 100644 --- a/tests/libtransmission/dht-test.cc +++ b/tests/libtransmission/dht-test.cc @@ -63,7 +63,7 @@ namespace libtransmission::test bool waitFor(struct event_base* event_base, std::chrono::milliseconds msec) { - return waitFor( + return waitFor( // event_base, []() { return false; }, msec); @@ -596,7 +596,7 @@ TEST_F(DhtTest, usesBootstrapFile) // Confirm that BootstrapNodeName gets pinged first. auto const expected = getSockaddr(BootstrapNodeName, BootstrapNodePort); auto& pinged = mediator.mock_dht_.pinged_; - waitFor( + waitFor( // event_base_, [&pinged]() { return !std::empty(pinged); }, 5s); diff --git a/tests/libtransmission/timer-test.cc b/tests/libtransmission/timer-test.cc index 914a5e813..fbbce0bb8 100644 --- a/tests/libtransmission/timer-test.cc +++ b/tests/libtransmission/timer-test.cc @@ -42,7 +42,7 @@ protected: void sleepMsec(std::chrono::milliseconds msec) { - EXPECT_FALSE(waitFor( + EXPECT_FALSE(waitFor( // evbase_.get(), []() { return false; }, msec)); diff --git a/web/assets/img/pause-circle-active.svg b/web/assets/img/pause-circle-active.svg index 2f2cb114a..7493ad671 100644 --- a/web/assets/img/pause-circle-active.svg +++ b/web/assets/img/pause-circle-active.svg @@ -1 +1,39 @@ - + + + + + + + + + + diff --git a/web/assets/img/pause-circle-idle.svg b/web/assets/img/pause-circle-idle.svg index 1c2f127ba..00ed842e3 100644 --- a/web/assets/img/pause-circle-idle.svg +++ b/web/assets/img/pause-circle-idle.svg @@ -1 +1,11 @@ - + + + + + <?xmlversion="1.0"encoding="UTF-8"?><!--Generator:AppleNativeCoreSVG232.5--><!DOCTYPEsvgPUBLIC"-//W3C//DTDSVG1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svgversion="1.1"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"width="60"height="59.7949"><g><rectheight="59.7949"opacity="0"width="60"x="0"y="0"/><pathd="M29.882859.7656C46.230559.765659.765646.201259.765629.8828C59.765613.535246.2012029.85350C13.53520013.5352029.8828C046.201213.564559.765629.882859.7656Z"fill="#808080"/><pathd="M21.357441.6602C19.863341.660219.189540.839819.189539.668L19.189520.0391C19.189518.896519.863318.076221.357418.0762L24.316418.0762C25.839818.076226.513718.896526.513720.0391L26.513739.668C26.513740.839825.839841.660224.316441.6602ZM35.507841.6602C33.984441.660233.310540.839833.310539.668L33.310520.0391C33.310518.896533.984418.076235.507818.0762L38.466818.0762C39.931618.076240.605518.896540.605520.0391L40.605539.668C40.605540.839839.931641.660238.466841.6602Z"fill="#ffffff"/></g></svg> + + + + + + diff --git a/web/assets/img/play-circle-active.svg b/web/assets/img/play-circle-active.svg index b8e97e4f8..998a49a5e 100644 --- a/web/assets/img/play-circle-active.svg +++ b/web/assets/img/play-circle-active.svg @@ -1 +1,39 @@ - + + + + + + + + + + diff --git a/web/assets/img/play-circle-idle.svg b/web/assets/img/play-circle-idle.svg index 816b68731..83bcf27c2 100644 --- a/web/assets/img/play-circle-idle.svg +++ b/web/assets/img/play-circle-idle.svg @@ -1 +1,11 @@ - + + + + + <?xmlversion="1.0"encoding="UTF-8"?><!--Generator:AppleNativeCoreSVG232.5--><!DOCTYPEsvgPUBLIC"-//W3C//DTDSVG1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svgversion="1.1"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"width="60"height="59.7949"><g><rectheight="59.7949"opacity="0"width="60"x="0"y="0"/><pathd="M29.882859.7656C46.230559.765659.765646.201259.765629.8828C59.765613.535246.2012029.85350C13.53520013.5352029.8828C046.201213.564559.765629.882859.7656Z"fill="#808080"/><pathd="M24.316441.6895C22.910242.539121.298841.865221.298840.4004L21.298819.3945C21.298817.95923.027317.343824.316418.1055L41.513728.3008C42.744129.033242.773430.79141.513731.5527Z"fill="#ffffff"/></g></svg> + + + + + +