webview.qml 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. import QtQuick 2.4
  2. import Konvergo 1.0
  3. import QtWebEngine 1.1
  4. import QtWebChannel 1.0
  5. import QtQuick.Window 2.2
  6. import QtQuick.Controls 1.4
  7. KonvergoWindow
  8. {
  9. id: mainWindow
  10. title: "Jellyfin Media Player"
  11. objectName: "mainWindow"
  12. minimumHeight: windowMinSize.height
  13. minimumWidth: windowMinSize.width
  14. function runWebAction(action)
  15. {
  16. if (mainWindow.webDesktopMode)
  17. web.triggerWebAction(action)
  18. }
  19. Action
  20. {
  21. enabled: mainWindow.webDesktopMode
  22. shortcut: {
  23. if (components.system.isMacos) return "Ctrl+Shift+F";
  24. return "F11";
  25. }
  26. onTriggered: mainWindow.toggleWebMode()
  27. }
  28. Action
  29. {
  30. enabled: mainWindow.webDesktopMode
  31. shortcut:
  32. {
  33. if (components.system.isMacos) return "Ctrl+Meta+F"
  34. return "Shift+F11"
  35. }
  36. onTriggered: mainWindow.toggleFullscreen()
  37. }
  38. Action
  39. {
  40. shortcut: "Alt+Return"
  41. enabled:
  42. {
  43. if (mainWindow.webDesktopMode && components.system.isWindows)
  44. return true;
  45. return false;
  46. }
  47. onTriggered: mainWindow.toggleFullscreen()
  48. }
  49. Action
  50. {
  51. enabled: mainWindow.webDesktopMode
  52. shortcut: StandardKey.Close
  53. onTriggered: mainWindow.close()
  54. }
  55. Action
  56. {
  57. enabled: mainWindow.webDesktopMode
  58. shortcut: {
  59. if (components.system.isMacos) return "Ctrl+M";
  60. return "Meta+Down";
  61. }
  62. onTriggered: mainWindow.minimizeWindow()
  63. }
  64. Action
  65. {
  66. enabled: mainWindow.webDesktopMode
  67. shortcut: StandardKey.Quit
  68. onTriggered: mainWindow.close()
  69. }
  70. Action
  71. {
  72. shortcut: "Ctrl+Shift+D"
  73. enabled: mainWindow.webDesktopMode
  74. onTriggered: mainWindow.toggleDebug()
  75. }
  76. Action
  77. {
  78. shortcut: StandardKey.Copy
  79. onTriggered: runWebAction(WebEngineView.Copy)
  80. id: action_copy
  81. }
  82. Action
  83. {
  84. shortcut: StandardKey.Cut
  85. onTriggered: runWebAction(WebEngineView.Cut)
  86. id: action_cut
  87. }
  88. Action
  89. {
  90. shortcut: StandardKey.Paste
  91. onTriggered: runWebAction(WebEngineView.Paste)
  92. id: action_paste
  93. }
  94. Action
  95. {
  96. shortcut: StandardKey.SelectAll
  97. onTriggered: runWebAction(WebEngineView.SelectAll)
  98. id: action_selectall
  99. }
  100. Action
  101. {
  102. shortcut: StandardKey.Undo
  103. onTriggered: runWebAction(WebEngineView.Undo)
  104. id: action_undo
  105. }
  106. Action
  107. {
  108. shortcut: StandardKey.Redo
  109. onTriggered: runWebAction(WebEngineView.Redo)
  110. id: action_redo
  111. }
  112. MpvVideo
  113. {
  114. id: video
  115. objectName: "video"
  116. // It's not a real item. Its renderer draws onto the view's background.
  117. width: 0
  118. height: 0
  119. visible: false
  120. }
  121. WebEngineView
  122. {
  123. id: web
  124. objectName: "web"
  125. settings.errorPageEnabled: false
  126. settings.localContentCanAccessRemoteUrls: true
  127. profile.httpUserAgent: components.system.getUserAgent()
  128. url: mainWindow.webUrl
  129. focus: true
  130. property string currentHoveredUrl: ""
  131. onLinkHovered: web.currentHoveredUrl = hoveredUrl
  132. width: mainWindow.width
  133. height: mainWindow.height
  134. Component.onCompleted:
  135. {
  136. forceActiveFocus()
  137. mainWindow.reloadWebClient.connect(reload)
  138. }
  139. onLoadingChanged:
  140. {
  141. // we use a timer here to switch to the webview since
  142. // it take a few moments for the webview to render
  143. // after it has loaded.
  144. //
  145. if (loadRequest.status == WebEngineView.LoadStartedStatus)
  146. {
  147. console.log("WebEngineLoadRequest starting: " + loadRequest.url);
  148. }
  149. else if (loadRequest.status == WebEngineView.LoadSucceededStatus)
  150. {
  151. console.log("WebEngineLoadRequest success: " + loadRequest.url);
  152. }
  153. else if (loadRequest.status == WebEngineView.LoadFailedStatus)
  154. {
  155. console.log("WebEngineLoadRequest failure: " + loadRequest.url + " error code: " + loadRequest.errorCode);
  156. errorLabel.visible = true
  157. errorLabel.text = "Error loading client, this is bad and should not happen<br>" +
  158. "You can try to <a href='reload'>reload</a> or head to our <a href='http://jellyfin.org'>support page</a><br><br>Actual Error: <pre>" +
  159. loadRequest.errorString + " [" + loadRequest.errorCode + "]</pre><br><br>" +
  160. "Provide the <a target='_blank' href='file://"+ components.system.logFilePath + "'>logfile</a> as well."
  161. }
  162. }
  163. onNewViewRequested:
  164. {
  165. if (request.userInitiated)
  166. {
  167. console.log("Opening external URL: " + web.currentHoveredUrl)
  168. components.system.openExternalUrl(web.currentHoveredUrl)
  169. }
  170. }
  171. onFullScreenRequested:
  172. {
  173. console.log("Request fullscreen: " + request.toggleOn)
  174. mainWindow.setFullScreen(request.toggleOn)
  175. request.accept()
  176. }
  177. onJavaScriptConsoleMessage:
  178. {
  179. components.system.info(message)
  180. }
  181. onCertificateError:
  182. {
  183. console.log(error.url + " :" + error.description + error.error)
  184. }
  185. }
  186. Text
  187. {
  188. id: errorLabel
  189. z: 5
  190. anchors.centerIn: parent
  191. color: "#999999"
  192. linkColor: "#a85dc3"
  193. text: "Generic error"
  194. font.pixelSize: 32
  195. font.bold: true
  196. visible: false
  197. verticalAlignment: Text.AlignVCenter
  198. textFormat: Text.StyledText
  199. onLinkActivated:
  200. {
  201. if (link == "reload")
  202. {
  203. errorLabel.visible = false
  204. web.reload()
  205. }
  206. else
  207. {
  208. Qt.openUrlExternally(link)
  209. }
  210. }
  211. }
  212. Rectangle
  213. {
  214. id: debug
  215. color: "black"
  216. z: 10
  217. anchors.centerIn: parent
  218. width: parent.width
  219. height: parent.height
  220. opacity: 0.7
  221. visible: mainWindow.showDebugLayer
  222. Text
  223. {
  224. id: debugLabel
  225. width: (parent.width - 50) / 2
  226. height: parent.height - 25
  227. anchors.left: parent.left
  228. anchors.leftMargin: 64
  229. anchors.top: parent.top
  230. anchors.topMargin: 54
  231. anchors.bottomMargin: 54
  232. color: "white"
  233. font.pixelSize: Math.round(height / 65)
  234. wrapMode: Text.WrapAnywhere
  235. function windowDebug()
  236. {
  237. var dbg = mainWindow.debugInfo + "Window and web\n";
  238. dbg += " Window size: " + parent.width + "x" + parent.height + " - " + web.width + "x" + web.height + "\n";
  239. dbg += " DevicePixel ratio: " + Screen.devicePixelRatio + "\n";
  240. return dbg;
  241. }
  242. text: windowDebug()
  243. }
  244. Text
  245. {
  246. id: videoLabel
  247. width: (parent.width - 50) / 2
  248. height: parent.height - 25
  249. anchors.right: parent.right
  250. anchors.left: debugLabel.right
  251. anchors.rightMargin: 64
  252. anchors.top: parent.top
  253. anchors.topMargin: 54
  254. anchors.bottomMargin: 54
  255. color: "white"
  256. font.pixelSize: Math.round(height / 65)
  257. wrapMode: Text.WrapAnywhere
  258. text: mainWindow.videoInfo
  259. }
  260. }
  261. property QtObject webChannel: web.webChannel
  262. }