Hello community, here is the log from the commit of package orion for openSUSE:Factory checked in at 2018-10-15 09:46:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/orion (Old) and /work/SRC/openSUSE:Factory/.orion.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "orion" Mon Oct 15 09:46:37 2018 rev:18 rq:641949 version:1.6.5+git~20181007 Changes: -------- --- /work/SRC/openSUSE:Factory/orion/orion.changes 2018-07-06 10:45:39.618992982 +0200 +++ /work/SRC/openSUSE:Factory/.orion.new/orion.changes 2018-10-15 09:47:45.719081961 +0200 @@ -1,0 +2,27 @@ +Sun Oct 07 19:43:27 UTC 2018 - pousaduarte@gmail.com + +- Update to version 1.6.5+git~20181007: + * version 1.6.6 + * fix header visibility while mouseover player + * add player hotkeys + * improve player ui + * fix some player ui glitches + * add channel name to header when playing vod + * fix vod reload seeking to correct position + * fix QtAV buffering status and seeking at start + * fix mpv player position update + * replace spacer with vod time label + * add option for hardware acceleration + * add option for opengl backend + * add option for multiple instances + * fix wrong usage of beginRemoveRows + +------------------------------------------------------------------- +Sat Oct 06 23:18:48 UTC 2018 - pousaduarte@gmail.com + +- Update to version 1.6.5+git~20181005: + * enable android topbar hiding feature on desktop + * fix appveyor (#245) + * add example image of color mod + +------------------------------------------------------------------- Old: ---- orion-1.6.5+git~20180524.tar.xz New: ---- orion-1.6.5+git~20181007.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ orion.spec ++++++ --- /var/tmp/diff_new_pack.9136pa/_old 2018-10-15 09:47:47.351080146 +0200 +++ /var/tmp/diff_new_pack.9136pa/_new 2018-10-15 09:47:47.351080146 +0200 @@ -12,12 +12,12 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: orion -Version: 1.6.5+git~20180524 +Version: 1.6.5+git~20181007 Release: 0 Summary: Twitch stream client using Qt License: GPL-3.0-only ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.9136pa/_old 2018-10-15 09:47:47.387080106 +0200 +++ /var/tmp/diff_new_pack.9136pa/_new 2018-10-15 09:47:47.387080106 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/alamminsalo/orion.git</param> - <param name="changesrevision">eda7f7e0f1802671a819fab605ec29adea22a9c9</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">29dfd55c3332dd36b361d7d6dded8b17c28f9159</param></service></servicedata> \ No newline at end of file ++++++ orion-1.6.5+git~20180524.tar.xz -> orion-1.6.5+git~20181007.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/README.md new/orion-1.6.5+git~20181007/README.md --- old/orion-1.6.5+git~20180524/README.md 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/README.md 2018-10-07 17:50:22.000000000 +0200 @@ -87,6 +87,18 @@ ## Misc Supports environment variables such as `QT_QUICK_CONTROLS_MATERIAL_ACCENT`, to customize UI colors. + +### Example + +``` +# linux example, but similar in other OSes +QT_QUICK_CONTROLS_MATERIAL_BACKGROUND="#00101f" QT_QUICK_CONTROLS_MATERIAL_ACCENT="#FF5722" orion +``` + +And this looks like: + +<img src="https://user-images.githubusercontent.com/5585454/42691905-8438a3fe-86b2-11e..." width="256"> + See more on [qt material docs](https://doc.qt.io/qt-5/qtquickcontrols2-material.html). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/appveyor.yml new/orion-1.6.5+git~20181007/appveyor.yml --- old/orion-1.6.5+git~20180524/appveyor.yml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/appveyor.yml 2018-10-07 17:50:22.000000000 +0200 @@ -1,47 +1,72 @@ -# For info about dev tool paths on Appveyor see https://www.appveyor.com/docs/build-environment/#pre-installed-software - environment: matrix: - - platform: x86 - configuration: release - - platform: x64 - configuration: release - - platform: x86 - configuration: debug - - platform: x64 - configuration: debug + - platform: x64 + configuration: release + qt: 5.10 + cc: VS2017 + QTDIR: C:\Qt\5.10\msvc2017_64 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + OPENSSL_DIR: C:\OpenSSL-Win64 + + - platform: x86 + configuration: release + qt: 5.10 + cc: VS2015 + toolchain_version: 14 + QTDIR: C:\Qt\5.10\msvc2015 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + OPENSSL_DIR: C:\OpenSSL-Win32 + +matrix: + fast_finish: false + +cache: + - C:\projects\AV -> appveyor.yml + +init: + - set vcarch=%platform% + - set arch=%platform% + - set CL=/MP + - if "%platform%" == "x64" set vcarch=amd64 + - set VCREDIST=vcredist_%platform%.exe + - if %cc%==VS2017 set VCREDIST=vc_redist.%platform%.exe + - if %cc%==VS2017 ( + call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" %vcarch% + ) else if not %cc%==MinGW ( + call "C:\Program Files (x86)\Microsoft Visual Studio %toolchain_version%.0\VC\vcvarsall.bat" %vcarch% + ) + - set PATH=%QTDIR%\bin;%PATH% + - if %cc%==MinGW set PATH=C:\Qt\Tools\mingw%toolchain_version%_32\bin;%PATH% + - echo NUMBER_OF_PROCESSORS=%NUMBER_OF_PROCESSORS% + - echo PROCESSOR_IDENTIFIER=%PROCESSOR_IDENTIFIER% + - echo QTDIR=%QTDIR% + - echo PATH=%PATH% install: - - if %platform%==x86 set QTDIR=C:\Qt\5.9.3\msvc2015 - - if %platform%==x64 set QTDIR=C:\Qt\5.9.3\msvc2015_64 - - if %platform%==x86 set PATH=%QTDIR%\bin;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin;%PATH% - - if %platform%==x64 set PATH=%QTDIR%\bin;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin;%PATH% - - set INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt - - if %platform%==x86 set LIB=%QTDIR%\lib;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x86 - - if %platform%==x64 set LIB=%QTDIR%\lib;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\lib\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\x64 - - set VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC - - if %platform%==x86 set OPENSSL_DIR=C:\OpenSSL-Win32 - - if %platform%==x64 set OPENSSL_DIR=C:\OpenSSL-Win64 + - git clone https://github.com/wang-bin/QtAV.git "C:\projects\QtAV" + - cd "C:\projects\QtAV" && git submodule update --init + - cd "C:\projects" && C:\projects\QtAV\tools\ci\win\install_dep.bat + - cd "C:\projects\QtAV" + - qmake QtAV.pro "CONFIG+=%configuration%" "CONFIG+=no-examples" "CONFIG+=no-tests" + - nmake %configuration% + - sdk_install.bat + +before_build: + - echo APPVEYOR_BUILD_FOLDER=%APPVEYOR_BUILD_FOLDER% + - cd %APPVEYOR_BUILD_FOLDER% + - git submodule update --init build_script: -- cmd: >- - echo APPVEYOR_BUILD_FOLDER=%APPVEYOR_BUILD_FOLDER% - - cd %APPVEYOR_BUILD_FOLDER% - - qmake orion.pro "CONFIG+=multimedia" - - mkdir libs - - copy /y "%OPENSSL_DIR%\ssleay32.dll" libs - - copy /y "%OPENSSL_DIR%\libeay32.dll" libs - - nmake %configuration% - - %QTDIR%\bin\windeployqt --qmldir src\qml %configuration%\orion.exe - - dir /s + - qmake orion.pro "CONFIG+=%configuration%" "CONFIG+=qtav" + - mkdir libs + - copy /y "%OPENSSL_DIR%\ssleay32.dll" libs + - copy /y "%OPENSSL_DIR%\libeay32.dll" libs + - nmake %configuration% + - windeployqt --qmldir src\qml %configuration%\orion.exe + - copy /y %QTDIR%\bin\av*-*.dll %configuration% + - copy /y %QTDIR%\bin\sw*-*.dll %configuration% + - copy /y %QTDIR%\bin\QtAV*.dll %configuration% + - dir /s after_build: - 7z a orion_%configuration%_%platform%_snapshot_%APPVEYOR_REPO_COMMIT%.zip . -x!.git @@ -50,7 +75,7 @@ - del %configuration%\*.h - del %configuration%\*.res - if %configuration%==release copy "resources\orion-installer.iss" orion-installer.iss - - if %configuration%==release "C:\Program Files (x86)\Inno Setup 5\iscc.exe" /DPlatform=%platform% /DAdditionalRedist="C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_%platform%.exe" /F"orion-%configuration%-%platform%" "orion-installer.iss" + - if %configuration%==release "C:\Program Files (x86)\Inno Setup 5\iscc.exe" /DPlatform=%platform% /DAdditionalRedist="%APPVEYOR_BUILD_FOLDER%\%configuration%\%VCREDIST%" /F"orion-%configuration%-%platform%" "orion-installer.iss" artifacts: - path: orion_$(configuration)_$(platform)_snapshot_$(APPVEYOR_REPO_COMMIT).zip diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/orion.pro new/orion-1.6.5+git~20181007/orion.pro --- old/orion-1.6.5+git~20180524/orion.pro 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/orion.pro 2018-10-07 17:50:22.000000000 +0200 @@ -13,7 +13,7 @@ TARGET = orion -VERSION = 1.6.5 +VERSION = 1.6.6 DEFINES += APP_VERSION=\\\"v$$VERSION\\\" DEFINES += APP_NAME=\\\"Orion\\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/resources/orion-installer.iss new/orion-1.6.5+git~20181007/resources/orion-installer.iss --- old/orion-1.6.5+git~20180524/resources/orion-installer.iss 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/resources/orion-installer.iss 2018-10-07 17:50:22.000000000 +0200 @@ -39,7 +39,6 @@ Name: "{group}\Orion"; Filename: "{app}\bin\orion.exe" [Run] -Filename: "{app}\bin\vcredist_{#Platform}.exe"; Parameters: "/install /passive /norestart" #ifdef AdditionalRedist #define AdditionalRedistProper ExtractFileName(AdditionalRedist) Filename: "{app}\AdditionalRedist\{#AdditionalRedistProper}"; Parameters: "/install /passive /norestart" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/main.cpp new/orion-1.6.5+git~20181007/src/main.cpp --- old/orion-1.6.5+git~20180524/src/main.cpp 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/main.cpp 2018-10-07 17:50:22.000000000 +0200 @@ -80,6 +80,33 @@ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + // Load app settings + SettingsManager::getInstance()->load(); + + auto opengl = SettingsManager::getInstance()->opengl().toLower(); + + // OpenGL implementation used to render app. + // Need to be set before constructing QGuiApplication + // http://doc.qt.io/qt-5/qt.html#ApplicationAttribute-enum + if (opengl.contains("desktop")) { + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); + } else if(opengl.contains("software")) { + QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); + } else { + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); +#ifdef QT_OPENGL_DYNAMIC + qputenv("QT_OPENGL", "angle"); +#endif +#ifdef Q_OS_WIN + if (opengl.contains("d3d11")) + qputenv("QT_ANGLE_PLATFORM", "d3d11"); + else if (opengl.contains("d3d9")) + qputenv("QT_ANGLE_PLATFORM", "d3d9"); + else if (opengl.contains("warp")) + qputenv("QT_ANGLE_PLATFORM", "warp"); +#endif + } + #ifndef Q_OS_ANDROID QApplication app(argc, argv); #else @@ -97,13 +124,6 @@ NetworkManager::initialize(engine.networkAccessManager()); #ifndef Q_OS_ANDROID - //Single application solution - QLockFile lockfile(QDir::temp().absoluteFilePath("wz0dPKqHv3vX0BBsUFZt.lock")); - if (!lockfile.tryLock(100)) { - // Already running - return -1; - } - QCommandLineParser parser; parser.setApplicationDescription("Twitch.tv client"); parser.addHelpOption(); @@ -148,13 +168,28 @@ rootContext->setContextProperty("g_games", ChannelManager::getInstance()->getGamesModel()); rootContext->setContextProperty("vodsModel", VodManager::getInstance()->getModel()); + + rootContext->setContextProperty("g_instance", "main"); + +#ifndef Q_OS_ANDROID + //Single application solution + QLockFile lockfile(QDir::temp().absoluteFilePath("wz0dPKqHv3vX0BBsUFZt.lock")); + if (!lockfile.tryLock(100)) { + // Already running + if (!SettingsManager::getInstance()->multipleInstances()) { + return -1; + } + rootContext->setContextProperty("g_instance", "child"); + } +#endif + // Register qml components registerQmlComponents(&app); // Load QML content engine.load(QUrl("qrc:/main.qml")); - // Load app settings + // Trigger setting property notifications SettingsManager::getInstance()->load(); #ifndef Q_OS_ANDROID diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/channellistmodel.cpp new/orion-1.6.5+git~20181007/src/model/channellistmodel.cpp --- old/orion-1.6.5+git~20180524/src/model/channellistmodel.cpp 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/model/channellistmodel.cpp 2018-10-07 17:50:22.000000000 +0200 @@ -214,14 +214,16 @@ void ChannelListModel::clearView() { //Gives a sign to drop all channels from view, without removing them - beginRemoveRows(QModelIndex(), 0, channels.size()); - endRemoveRows(); + if (!channels.isEmpty()) { + beginRemoveRows(QModelIndex(), 0, channels.size() - 1); + endRemoveRows(); + } } void ChannelListModel::clear() { if (!channels.isEmpty()){ - beginRemoveRows(QModelIndex(), 0, channels.size()); + beginRemoveRows(QModelIndex(), 0, channels.size() - 1); qDeleteAll(channels); channels.clear(); channelIdIndex.clear(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/gamelistmodel.cpp new/orion-1.6.5+git~20181007/src/model/gamelistmodel.cpp --- old/orion-1.6.5+git~20180524/src/model/gamelistmodel.cpp 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/model/gamelistmodel.cpp 2018-10-07 17:50:22.000000000 +0200 @@ -118,7 +118,7 @@ void GameListModel::clear() { if (!games.isEmpty()){ - beginRemoveRows(QModelIndex(), 0, games.size()); + beginRemoveRows(QModelIndex(), 0, games.size() - 1); qDeleteAll(games); games.clear(); endRemoveRows(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/settingsmanager.cpp new/orion-1.6.5+git~20181007/src/model/settingsmanager.cpp --- old/orion-1.6.5+git~20180524/src/model/settingsmanager.cpp 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/model/settingsmanager.cpp 2018-10-07 17:50:22.000000000 +0200 @@ -12,13 +12,20 @@ //Initial values mAlert = true; mCloseToTray = false; + mMultipleInstances = false; mAlertPosition = 1; mMinimizeOnStartup = false; mTextScaleFactor = 1.0; mVolumeLevel = 100; mOfflineNotifications = false; mAccessToken = ""; +#ifdef Q_OS_WIN + mOpengl = "angle (d3d9)"; +#else + mOpengl = "opengl es"; +#endif mQuality = "source"; + mDecoder = "auto"; mChatEdge = 1; mLightTheme = false; mFont = ""; @@ -50,14 +57,26 @@ setCloseToTray(settings->value("closeToTray").toBool()); } + if (settings->contains("multipleInstances")) { + setMultipleInstances(settings->value("multipleInstances").toBool()); + } + if (settings->contains("minimizeOnStartup")) { setMinimizeOnStartup(settings->value("minimizeOnStartup").toBool()); } + if (settings->contains("opengl")) { + setOpengl(settings->value("opengl").toString()); + } + if (settings->contains("quality")) { setQuality(settings->value("quality").toString()); } + if (settings->contains("decoder")) { + setDecoder(settings->value("decoder").toString()); + } + if (settings->contains("volumeLevel")) { setVolumeLevel(settings->value("volumeLevel").toInt()); } @@ -123,6 +142,22 @@ emit closeToTrayChanged(); } +bool SettingsManager::multipleInstances() const +{ + return mMultipleInstances; +} + +void SettingsManager::setMultipleInstances(bool multipleInstances) +{ + if (mMultipleInstances != multipleInstances) { + mMultipleInstances = multipleInstances; + settings->setValue("multipleInstances", multipleInstances); + + qDebug() << "multipleInstances changed to" << multipleInstances; + } + emit multipleInstancesChanged(); +} + int SettingsManager::alertPosition() const { return mAlertPosition; @@ -231,6 +266,22 @@ emit textScaleFactorChanged(); } +QString SettingsManager::opengl() const +{ + return mOpengl; +} + +void SettingsManager::setOpengl(const QString &opengl) +{ + if (mOpengl != opengl) { + mOpengl = opengl; + settings->setValue("opengl", opengl); + + qDebug() << "opengl changed to" << opengl; + } + emit openglChanged(); +} + QString SettingsManager::quality() const { return mQuality; @@ -247,6 +298,22 @@ emit qualityChanged(); } +QString SettingsManager::decoder() const +{ + return mDecoder; +} + +void SettingsManager::setDecoder(const QString &decoder) +{ + if (mDecoder != decoder) { + mDecoder = decoder; + settings->setValue("decoder", decoder); + + qDebug() << "decoder changed to" << decoder; + } + emit decoderChanged(); +} + QString SettingsManager::accessToken() const { return mAccessToken; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/settingsmanager.h new/orion-1.6.5+git~20181007/src/model/settingsmanager.h --- old/orion-1.6.5+git~20180524/src/model/settingsmanager.h 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/model/settingsmanager.h 2018-10-07 17:50:22.000000000 +0200 @@ -12,13 +12,16 @@ Q_PROPERTY(bool alert READ alert WRITE setAlert NOTIFY alertChanged) Q_PROPERTY(bool closeToTray READ closeToTray WRITE setCloseToTray NOTIFY closeToTrayChanged) + Q_PROPERTY(bool multipleInstances READ multipleInstances WRITE setMultipleInstances NOTIFY multipleInstancesChanged) Q_PROPERTY(int alertPosition READ alertPosition WRITE setAlertPosition NOTIFY alertPositionChanged) Q_PROPERTY(int volumeLevel READ volumeLevel WRITE setVolumeLevel NOTIFY volumeLevelChanged) Q_PROPERTY(bool minimizeOnStartup READ minimizeOnStartup WRITE setMinimizeOnStartup NOTIFY minimizeOnStartupChanged) Q_PROPERTY(int chatEdge READ chatEdge WRITE setChatEdge NOTIFY chatEdgeChanged) Q_PROPERTY(bool offlineNotifications READ offlineNotifications WRITE setOfflineNotifications NOTIFY offlineNotificationsChanged) Q_PROPERTY(double textScaleFactor READ textScaleFactor WRITE setTextScaleFactor NOTIFY textScaleFactorChanged) + Q_PROPERTY(QString opengl READ opengl WRITE setOpengl NOTIFY openglChanged) Q_PROPERTY(QString quality READ quality WRITE setQuality NOTIFY qualityChanged) + Q_PROPERTY(QString decoder READ decoder WRITE setDecoder NOTIFY decoderChanged) Q_PROPERTY(QString accessToken READ accessToken WRITE setAccessToken NOTIFY accessTokenChanged) Q_PROPERTY(bool hasAccessToken READ hasAccessToken NOTIFY accessTokenChanged) Q_PROPERTY(bool lightTheme READ lightTheme WRITE setLightTheme NOTIFY lightThemeChanged) @@ -28,13 +31,16 @@ bool mAlert; bool mCloseToTray; + bool mMultipleInstances; int mAlertPosition; int mVolumeLevel; bool mMinimizeOnStartup; bool mSwapChat; bool mOfflineNotifications; double mTextScaleFactor; + QString mOpengl; QString mQuality; + QString mDecoder; QString mAccessToken; int mChatEdge; bool mLightTheme; @@ -54,6 +60,9 @@ bool closeToTray() const; void setCloseToTray(bool closeToTray); + bool multipleInstances() const; + void setMultipleInstances(bool multipleInstances); + int alertPosition() const; void setAlertPosition(int alertPosition); @@ -72,9 +81,15 @@ double textScaleFactor() const; void setTextScaleFactor(double textScaleFactor); + QString opengl() const; + void setOpengl(const QString &opengl); + QString quality() const; void setQuality(const QString &quality); + QString decoder() const; + void setDecoder(const QString &decoder); + QString accessToken() const; void setHiDpi(bool dpi); @@ -93,13 +108,16 @@ signals: void alertChanged(); void closeToTrayChanged(); + void multipleInstancesChanged(); void alertPositionChanged(); void volumeLevelChanged(); void minimizeOnStartupChanged(); void chatEdgeChanged(); void offlineNotificationsChanged(); void textScaleFactorChanged(); + void openglChanged(); void qualityChanged(); + void decoderChanged(); void lightThemeChanged(); void accessTokenChanged(QString accessToken); void fontChanged(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/vodlistmodel.cpp new/orion-1.6.5+git~20181007/src/model/vodlistmodel.cpp --- old/orion-1.6.5+git~20180524/src/model/vodlistmodel.cpp 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/model/vodlistmodel.cpp 2018-10-07 17:50:22.000000000 +0200 @@ -114,7 +114,7 @@ void VodListModel::clear() { if (!vods.isEmpty()){ - beginRemoveRows(QModelIndex(), 0, vods.size()); + beginRemoveRows(QModelIndex(), 0, vods.size() - 1); qDeleteAll(vods); vods.clear(); endRemoveRows(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/player/mpvobject.cpp new/orion-1.6.5+git~20181007/src/player/mpvobject.cpp --- old/orion-1.6.5+git~20180524/src/player/mpvobject.cpp 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/player/mpvobject.cpp 2018-10-07 17:50:22.000000000 +0200 @@ -26,6 +26,7 @@ #endif // Make use of the MPV_SUB_API_OPENGL_CB API. + mpv::qt::set_option_variant(mpv, "gpu-context", "angle"); mpv::qt::set_option_variant(mpv, "vo", "opengl-cb"); //mpv::qt::set_option_variant(mpv, "input-cursor", "no"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/MpvBackend.qml new/orion-1.6.5+git~20181007/src/qml/MpvBackend.qml --- old/orion-1.6.5+git~20180524/src/qml/MpvBackend.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/MpvBackend.qml 2018-10-07 17:50:22.000000000 +0200 @@ -25,6 +25,8 @@ stop() -- Stops playback seekTo(ms) -- Seeks to milliseconds in the current source, works only on vods setVolume(vol) -- Number between 0 - 100 +getDecoder() -- Return list of video decoders +setDecoder(idx) -- Set video decoder Signals needed: playingResumed() -- Signaled when playback toggles from paused / stopped to playing @@ -94,7 +96,29 @@ } function setVolume(vol) { - volume = Math.round(vol) + if (Qt.platform.os === "linux") + volume = Math.round(Math.log(vol) / Math.log(100)) + else + volume = Math.round(vol) + } + + function getDecoder() { + var defaultDecoders = [] + if (Qt.platform.os == "windows") { + defaultDecoders = [ "dxva2-copy", "d3d11va-copy", "cuda-copy", "no" ] + } else if (Qt.platform.os == "osx" || Qt.platform.os == "ios") { + defaultDecoders = [ "videotoolbox", "no" ] + } else if(Qt.platform.os == "android") { + defaultDecoders = [ "mediacodec_embed", "no" ] + } else if (Qt.platform.os == "linux") { + defaultDecoders = [ "vaapi-copy", "vdpau-copy", "no" ] + } + return [ "auto" ].concat(defaultDecoders) + } + + function setDecoder(idx) { + var decoderName = getDecoder()[idx] + renderer.setProperty("hwdec", decoderName) } signal playingResumed() @@ -133,6 +157,16 @@ renderer.setProperty("volume", volume) } + Timer { + id: positionTimer + interval: 1000 + running: false + repeat: true + onTriggered: { + if (root.status === "PLAYING") + root.position += 1 + } + } MpvObject { id: renderer @@ -145,14 +179,17 @@ onPlayingStopped: { root.status = "STOPPED" + positionTimer.stop() } onPlayingPaused: { root.status = "PAUSED" + positionTimer.stop() } onPlayingResumed: { root.status = "PLAYING" + positionTimer.start() } onPositionChanged: { @@ -170,6 +207,8 @@ if (root.position !== adjustedPosition) root.position = adjustedPosition + + positionTimer.restart() } Component.onCompleted: { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/MultimediaBackend.qml new/orion-1.6.5+git~20181007/src/qml/MultimediaBackend.qml --- old/orion-1.6.5+git~20180524/src/qml/MultimediaBackend.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/MultimediaBackend.qml 2018-10-07 17:50:22.000000000 +0200 @@ -25,6 +25,8 @@ stop() -- Stops playback seekTo(pos) -- Seeks to milliseconds in the current source, works only on vods setVolume(vol) -- Number between 0 - 100 +getDecoder() -- Return list of video decoders +setDecoder(idx) -- Set video decoder Signals needed: playingResumed() -- Signaled when playback toggles from paused / stopped to playing @@ -86,6 +88,15 @@ volume = Math.round(vol) } + function getDecoder() { + var defaultDecoders = [] + return defaultDecoders + } + + function setDecoder(idx) { + + } + signal playingResumed() signal playingPaused() signal playingStopped() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/OptionsView.qml new/orion-1.6.5+git~20181007/src/qml/OptionsView.qml --- old/orion-1.6.5+git~20180524/src/qml/OptionsView.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/OptionsView.qml 2018-10-07 17:50:22.000000000 +0200 @@ -177,6 +177,64 @@ checked: Settings.keepOnTop onClicked: Settings.keepOnTop = checked } + + Switch { + visible: !isMobile() + id: mulipleInstancesOption + text: "Allow multiple instances" + checked: Settings.multipleInstances + onClicked: Settings.multipleInstances = checked + } + + RowLayout { + width: parent.width + + OptionCombo { + id: openglOption + text: "OpenGL (needs restart)" + model: { + var opengl = [ ] + if (Qt.platform.os === "windows") { + opengl = ["angle", "angle (d3d11)", "angle (d3d9)", "angle (warp)"] + } else { + opengl = ["opengl es"] + } + opengl = opengl.concat(["desktop", "software"]) + return opengl + } + Layout.fillWidth: true + property var defaultValue + + onActivated: { + Settings.opengl = model[currentIndex] + } + + Component.onCompleted: { + defaultValue = Settings.opengl + selectItem(defaultValue) + } + + function selectItem(name) { + for (var i in model) { + if (model[i] === name) { + currentIndex = i; + return; + } + } + //None found, attempt to select first item + currentIndex = 0 + } + } + + Button { + text: "Reset" + font.pointSize: 9 + onClicked: { + openglOption.selectItem(openglOption.defaultValue) + } + } + } + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/PlayerView.qml new/orion-1.6.5+git~20181007/src/qml/PlayerView.qml --- old/orion-1.6.5+git~20180524/src/qml/PlayerView.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/PlayerView.qml 2018-10-07 17:50:22.000000000 +0200 @@ -21,6 +21,8 @@ import app.orion 1.0 Page { + id: root + property int duration: -1 property var currentChannel property var streamMap @@ -30,10 +32,11 @@ property int lastSetPosition property bool headersVisible: true - //Android only onHeadersVisibleChanged: { - if (isMobile() && view.playerVisible) { + if (root.visible) { + pArea.hoverEnabled = false topbar.visible = headersVisible + disableTimer.restart() } } @@ -42,7 +45,6 @@ //Renderer interface property alias renderer: loader.item - id: root //Fix minimode header bar clip: true @@ -122,7 +124,7 @@ function loadAndPlay(){ var description = setWatchingTitle(); - var start = !isVod ? -1 : seekBar.position + var start = !isVod ? -1 : seekBar.value var url = streamMap[Settings.quality] @@ -211,11 +213,14 @@ } function setWatchingTitle(){ - var description = currentChannel.title - + (currentChannel.game ? " playing " + currentChannel.game : "") - + (isVod ? " (VOD)" : ""); - setHeaderText(description); - return description; + var description = "" + if (currentChannel) { + description = currentChannel.title + (isVod ? ("\r\n" + currentChannel.name) : "") + + (currentChannel.game ? " playing " + currentChannel.game : "") + + (isVod ? " (VOD)" : ""); + setHeaderText(description); + } + return description; } function loadStreams(streams) { @@ -270,7 +275,9 @@ VodManager.setVodLastPlaybackPosition(root.currentChannel.name, root.curVodId, newPos); } } - seekBar.value = newPos + if (!seekBar.pressed) { + seekBar.value = newPos + } } onPlayingResumed: { @@ -290,6 +297,88 @@ } } + Shortcut { + sequence: "Space" + context: Qt.ApplicationShortcut + onActivated: { + renderer.togglePause() + clickRect.run() + pArea.refreshHeaders() + } + } + + Shortcut { + sequence: "0" + context: Qt.ApplicationShortcut + onActivated: { + reloadStream() + pArea.refreshHeaders() + } + } + + Shortcut { + sequence: "f" + context: Qt.ApplicationShortcut + onActivated: { + appFullScreen = !appFullScreen + } + } + + Shortcut { + sequence: "Esc" + context: Qt.ApplicationShortcut + onActivated: { + appFullScreen = false + } + } + + Shortcut { + sequence: "m" + context: Qt.ApplicationShortcut + onActivated: { + volumeBtn.toggleMute() + pArea.refreshHeaders() + } + } + + Shortcut { + sequence: "Up" + context: Qt.ApplicationShortcut + onActivated: { + volumeSlider.value += 5 + pArea.refreshHeaders() + } + } + + Shortcut { + sequence: "Down" + context: Qt.ApplicationShortcut + onActivated: { + volumeSlider.value -= 5 + pArea.refreshHeaders() + } + } + + Shortcut { + sequence: "Right" + context: Qt.ApplicationShortcut + onActivated: { + if (!isVod || seekBar.pressed) return + seekBar.seek(seekBar.value + 5) + pArea.refreshHeaders() + } + } + + Shortcut { + sequence: "Left" + context: Qt.ApplicationShortcut + onActivated: { + if (!isVod || seekBar.pressed) return + seekBar.seek(seekBar.value - 5) + pArea.refreshHeaders() + } + } + Item { id: playerArea anchors.fill: parent @@ -328,10 +417,19 @@ anchors.fill: playerArea function refreshHeaders(){ - if (!hideTimer.running) + if (!hideTimer.running && !root.headersVisible) root.headersVisible = true hideTimer.restart() } + + Timer { + id: disableTimer + interval: 200 + running: false + onTriggered:{ + pArea.hoverEnabled = true + } + } onVisibleChanged: refreshHeaders() onPositionChanged: refreshHeaders() @@ -346,7 +444,7 @@ Label { id: clickRectIcon - text: renderer.status !== "PLAYING" ? "\ue037" : "\ue034" + text: "" anchors.centerIn: parent font.family: "Material Icons" font.pointSize: parent.width * 0.5 @@ -356,6 +454,15 @@ id: _anim running: false + onStarted: { + clickRectIcon.text = renderer.status !== "PLAYING" ? "\ue037" : "\ue034" + } + + onStopped: { + clickRect.opacity = 0 + clickRect.width = 0 + } + NumberAnimation { target: clickRect property: "width" @@ -377,19 +484,21 @@ function run() { _anim.restart() } + + function abort() { + _anim.stop() + } } onClicked: { clickRect.run() - - if (root.headersVisible && bottomBar.height > 50) - clickTimer.restart() - else - refreshHeaders() + clickTimer.restart() + refreshHeaders() } onDoubleClicked: { if (!isMobile()) { clickTimer.stop() + clickRect.abort(); appFullScreen = !appFullScreen } } @@ -400,7 +509,7 @@ Timer { //Dbl click timer id: clickTimer - interval: 440 + interval: 200 repeat: false onTriggered: { renderer.togglePause(); @@ -413,8 +522,18 @@ running: false repeat: false onTriggered: { - var itemUnder = pArea.childAt(pArea.mouseX, pArea.mouseY) - root.headersVisible = pArea.containsMouse && (itemUnder === bottomBar || itemUnder === headerBar) + if (!root.headersVisible || headerBarArea.containsMouse || bottomBarArea.containsMouse) return + + if (renderer.status === "PAUSED" || renderer.status === "STOPPED") return + + // Bug?: MouseArea doesn't work over Controls + var controls = [ favBtn, chatBtn, playBtn, resetBtn, volumeBtn, volumeSlider, seekBar, hwaccelBox, sourcesBox, cropBtn, fsBtn]; + for (var i = 0; i < controls.length; i++) { + if (controls[i].hovered || controls[i].pressed || controls[i].down) + return; + } + + root.headersVisible = false } } @@ -434,6 +553,7 @@ clip: true height: root.headersVisible ? 55 : 0 + visible: height > 0 Behavior on height { NumberAnimation { @@ -441,6 +561,12 @@ } } + MouseArea { + id: headerBarArea + anchors.fill: parent + hoverEnabled: true + } + RowLayout { anchors { fill: parent @@ -508,9 +634,9 @@ left: parent.left right: parent.right } - - clip: true + clip: false height: root.headersVisible ? 55 : 0 + visible: height > 0 Behavior on height { NumberAnimation { @@ -518,16 +644,85 @@ } } + MouseArea { + id: bottomBarArea + anchors.fill: parent + hoverEnabled: true + } + + Slider { + id: seekBar + from: 0 + to: duration + visible: isVod && headersVisible + padding: 0 + hoverEnabled: true + clip: true + + anchors { + verticalCenter: parent.top + left: parent.left + right: parent.right + } + + Component.onCompleted: { + handle.opacity = 0; + } + + PropertyAnimation { + id: handleAnimation + target: seekBar.handle + easing.type: Easing.OutQuad + property: "opacity" + duration: 400 + running: false + } + + onHoveredChanged: { + var wantedOpacity = hovered || pressed ? 1 : 0; + if (handle.opacity === wantedOpacity) return; + handleAnimation.to = wantedOpacity; + handleAnimation.restart(); + } + onPressedChanged: { + if (!pressed) + seekTo(value) + } + + property real prev: 0 + onValueChanged: { + if (seekTimer.running) + value = seekTimer.to + } + + Timer { + id: seekTimer + interval: 500 + repeat: false + property real to: 0 + onTriggered: { + seekTo(seekBar.value); + } + } + + function seek(val) { + seekTimer.to = val + value = val + seekTimer.restart() + } + } + RowLayout { anchors { fill: parent rightMargin: 5 leftMargin: 5 - } + } + spacing: 0 IconButtonFlat { id: playBtn - text: renderer.status !== "PLAYING" ? "\ue037" : "\ue034" + text: renderer.status !== "PLAYING" && renderer.status !== "BUFFERING" ? "\ue037" : "\ue034" onClicked: renderer.togglePause() } @@ -537,39 +732,21 @@ onClicked: reloadStream() } - //spacer - Item { - Layout.minimumWidth: 0 - Layout.fillWidth: true - } - - IconButtonFlat { - id: cropBtn - visible: !appFullScreen && !isMobile() && !chat.visible && parent.width > 440 - text: "\ue3bc" - onClicked: fitToAspectRatio() - } - - IconButtonFlat { - id: fsBtn - visible: !isMobile() - text: !appFullScreen ? "\ue5d0" : "\ue5d1" - onClicked: appFullScreen = !appFullScreen - } - IconButtonFlat { id: volumeBtn - visible: !isMobile() && parent.width > 390 + visible: !isMobile() property real mutedValue: 100.0 text: volumeSlider.value > 0 ? (volumeSlider.value > 50 ? "\ue050" : "\ue04d") : "\ue04f" onClicked: { + toggleMute() + } + function toggleMute() { if (volumeSlider.value > 0) { mutedValue = volumeSlider.value volumeSlider.value = 0 - } - else { + } else { volumeSlider.value = mutedValue } } @@ -579,19 +756,116 @@ id: volumeSlider from: 0 to: 100 + width: 0 + opacity: 0 visible: !isMobile() - Layout.maximumWidth: 90 + Layout.maximumWidth: width + hoverEnabled: true + + Behavior on width { PropertyAnimation { easing.type: Easing.InOutQuad } } + Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad } } + Component.onCompleted: { value = Settings.volumeLevel + renderer.setVolume(value) + + playBtn.hoverEnabled = true + resetBtn.hoverEnabled = true + volumeBtn.hoverEnabled = true + } + + Connections { target: playBtn; onHoveredChanged: volumeSlider.update(); onPressedChanged: volumeSlider.update() } + Connections { target: resetBtn; onHoveredChanged: volumeSlider.update(); onPressedChanged: volumeSlider.update() } + Connections { target: volumeBtn; onHoveredChanged: volumeSlider.update(); onPressedChanged: volumeSlider.update() } + + // Volume slider behavior similar to youtube + function update() { + if (opacity > 0 && (playBtn.hovered || resetBtn.hovered)) { + opacity = 1 + width = 90 + } else if (hovered || pressed || volumeBtn.hovered || volumeBtn.pressed) { + opacity = 1 + width = 90 + } else { + opacity = 0 + width = 0 + } } + onHoveredChanged: update() + onPressedChanged: update() + onValueChanged: { - var val = value - if (Qt.platform === "linux" && player_backend === "mpv") - val = Math.round(Math.log(val) / Math.log(100)) + renderer.setVolume(value) + Settings.volumeLevel = value; + } + } + + //spacer + Label { + id: videoPositionLabel + Layout.minimumWidth: 0 + Layout.fillWidth: true + font.bold: true + font.pointSize: 8 + Material.foreground: Material.Grey + horizontalAlignment: Qt.AlignLeft + clip: true + function updateText() { + if (!isVod) return "" + var formatTime = function(seconds) { + var d = new Date() + d.setTime(seconds * 1000) + d.setMinutes(d.getMinutes() + d.getTimezoneOffset()) + return d.toTimeString() + } + text = formatTime(seekBar.value) + "/" + formatTime(duration) + } + Connections { + target: seekBar + onValueChanged: videoPositionLabel.updateText() + } + Connections { + target: renderer + onPlayingStopped: videoPositionLabel.text = "" + } + } + + + ComboBox { + id: hwaccelBox + font.pointSize: 9 + font.bold: true + focusPolicy: Qt.NoFocus + flat: true + Layout.fillWidth: true + Layout.maximumWidth: 140 + Layout.minimumWidth: 100 + visible: renderer.getDecoder().length > 1 - renderer.setVolume(val) - Settings.volumeLevel = val; + onCurrentIndexChanged: { + renderer.setDecoder(currentIndex) + loadAndPlay() + Settings.decoder = hwaccelBox.model[currentIndex] + pArea.refreshHeaders() + } + + Component.onCompleted: { + var decoder = renderer.getDecoder() + hwaccelBox.model = decoder + selectItem(Settings.decoder) + renderer.setDecoder(currentIndex) + } + + function selectItem(name) { + for (var i in hwaccelBox.model) { + if (hwaccelBox.model[i] === name) { + currentIndex = i; + return; + } + } + //None found, attempt to select first item + currentIndex = 0 } } @@ -599,13 +873,14 @@ id: sourcesBox font.pointSize: 9 font.bold: true + focusPolicy: Qt.NoFocus flat: true Layout.fillWidth: true Layout.maximumWidth: 140 Layout.minimumWidth: 100 - onActivated: { - Settings.quality = sourcesBox.model[index] + onCurrentIndexChanged: { + Settings.quality = sourcesBox.model[currentIndex] loadAndPlay() pArea.refreshHeaders() } @@ -621,23 +896,20 @@ currentIndex = 0 } } - } - } - Slider { - id: seekBar - from: 0 - to: duration - visible: isVod && headersVisible - padding: 0 - anchors { - verticalCenter: bottomBar.top - left: parent.left - right: parent.right - } - onPressedChanged: { - if (!pressed) - seekTo(value) + IconButtonFlat { + id: cropBtn + visible: !appFullScreen && !isMobile() && !chat.visible && parent.width > 440 + text: "\ue3bc" + onClicked: fitToAspectRatio() + } + + IconButtonFlat { + id: fsBtn + visible: !isMobile() + text: !appFullScreen ? "\ue5d0" : "\ue5d1" + onClicked: appFullScreen = !appFullScreen + } } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/QtAVBackend.qml new/orion-1.6.5+git~20181007/src/qml/QtAVBackend.qml --- old/orion-1.6.5+git~20180524/src/qml/QtAVBackend.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/QtAVBackend.qml 2018-10-07 17:50:22.000000000 +0200 @@ -25,6 +25,8 @@ stop() -- Stops playback seekTo(pos) -- Seeks to milliseconds in the current source, works only on vods setVolume(vol) -- Number between 0 - 100 +getDecoder() -- Return list of video decoders +setDecoder(idx) -- Set video decoder Signals needed: playingResumed() -- Signaled when playback toggles from paused / stopped to playing @@ -48,12 +50,13 @@ stop(); + renderer.source = src + renderer.startPosition = 0 + if (start >= 0) { seekTo(start) } - renderer.source = src - resume() } @@ -77,6 +80,8 @@ } function seekTo(pos) { + status = "BUFFERING" + renderer.startPosition = pos * 1000 renderer.seek(pos * 1000) root.position = pos } @@ -85,6 +90,40 @@ volume = Math.round(vol) } + function getDecoder() { + var defaultDecoders = renderer.videoCodecs + var decoder = [ "auto" ] + decoder = decoder.concat(defaultDecoders); + return decoder + } + + function setDecoder(idx) { + var decoderName = getDecoder()[idx] + + var opt = renderer.videoCodecOptions + opt["copyMode"] = Qt.platform.os == "android" ? "OptimizedCopy" : "ZeroCopy" + renderer.videoCodecOptions = opt + + if (decoderName === "auto") { + if (g_instance === "child") { + // disable automatic hw acceleration for multiple instances (usually results in lag) + renderer.videoCodecPriority = [ "FFmpeg" ] + } else if (Qt.platform.os == "windows") { + renderer.videoCodecPriority = [ "DXVA", "FFmpeg" ] + } else if (Qt.platform.os == "winrt" || Qt.platform.os == "winphone") { + renderer.videoCodecPriority = [ "D3D11", "FFmpeg" ] + } else if (Qt.platform.os == "osx" || Qt.platform.os == "ios") { + renderer.videoCodecPriority = [ "VideoToolbox", "FFmpeg" ] + } else if(Qt.platform.os == "android") { + renderer.videoCodecPriority = [ "MediaCodec", "FFmpeg" ] + } else if (Qt.platform.os == "linux") { + renderer.videoCodecPriority = [ "VAAPI", "FFmpeg" ] + } + } else { + renderer.videoCodecPriority = [ decoderName ] + } + } + signal playingResumed() signal playingPaused() signal playingStopped() @@ -119,6 +158,22 @@ MediaPlayer { id: renderer + function updateStatus() { + if (status === MediaPlayer.Buffering) { + root.status = "BUFFERING" + } else if (playbackState === MediaPlayer.PlayingState) { + root.status = "PLAYING" + } else if (playbackState === MediaPlayer.PausedState) { + root.status = "PAUSED" + } else if (playbackState === MediaPlayer.StoppedState) { + root.status = "STOPPED" + } + } + + onStatusChanged: { + updateStatus() + } + onStopped: { root.status = "STOPPED" root.playingStopped() @@ -134,9 +189,14 @@ root.playingResumed() } + onSeekFinished: { + updateStatus() + } + onPositionChanged: { + if (root.status !== "PLAYING") return var pos = position / 1000 - if (root.position !== pos) + if (root.position !== pos && (startPosition === 0 || position > 0)) root.position = pos } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/components/IconButtonFlat.qml new/orion-1.6.5+git~20181007/src/qml/components/IconButtonFlat.qml --- old/orion-1.6.5+git~20180524/src/qml/components/IconButtonFlat.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/components/IconButtonFlat.qml 2018-10-07 17:50:22.000000000 +0200 @@ -5,4 +5,5 @@ font.pointSize: 16 flat: true font.family: "Material Icons" + focusPolicy: Qt.NoFocus } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/components/OptionCombo.qml new/orion-1.6.5+git~20181007/src/qml/components/OptionCombo.qml --- old/orion-1.6.5+git~20180524/src/qml/components/OptionCombo.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/components/OptionCombo.qml 2018-10-07 17:50:22.000000000 +0200 @@ -22,6 +22,7 @@ property alias text: label.text property alias selection: combo.currentIndex property alias model: combo.model + property alias currentIndex: combo.currentIndex signal activated(int index) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/irc/ChatView.qml new/orion-1.6.5+git~20181007/src/qml/irc/ChatView.qml --- old/orion-1.6.5+git~20180524/src/qml/irc/ChatView.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/irc/ChatView.qml 2018-10-07 17:50:22.000000000 +0200 @@ -157,6 +157,7 @@ id: pinBtn checkable: true font.family: "Material Icons" + focusPolicy: Qt.NoFocus text: checked ? "\ue897" : "\ue898" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/main.qml new/orion-1.6.5+git~20181007/src/qml/main.qml --- old/orion-1.6.5+git~20180524/src/qml/main.qml 2018-05-24 17:25:25.000000000 +0200 +++ new/orion-1.6.5+git~20181007/src/qml/main.qml 2018-10-07 17:50:22.000000000 +0200 @@ -47,7 +47,7 @@ || Screen.primaryOrientation === Qt.InvertedPortraitOrientation function fitToAspectRatio() { - height = Math.floor(view.width * 0.5625 + topbar.height) + height = Math.floor(view.width * 0.5625) } function isMobile() {