<commit_before>/*-
 * Copyright (c) 2014 <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of any co-contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.0
import Sailfish.Media 1.0
import "YoutubeClientV3.js" as Yt

Page {
    id: page
    allowedOrientations: Orientation.All
    showNavigationIndicator: page.isPortrait || (page.isLandscape && controls.visible())
    property string videoId
    property string title

    Rectangle {
        id: background;
        anchors.fill: parent
        color: "black"
    }

    SilicaFlickable {
        id: flickable
        anchors.fill: parent

        PageHeader {
            id: header
            title: page.title
            visible: page.isPortrait || (page.isLandscape && controls.visible())
            z: video.z + 2
        }

        // Simple background for PageHeader visible only when player is in landscape mode.
        // It's supposed to ensure header contents are always readeble, no matter what
        // video content is visible in the background.
        Rectangle {
            anchors {
                right: header.right
                left: header.left
                top: header.top
                bottom: header.bottom
            }

            visible: header.visible
            color: "black"
            opacity: 0.5
            z: header.z - 1
        }

        MediaPlayer {
            id: mediaPlayer
            autoPlay: true

            onStatusChanged: {
                console.debug("Media Player status changed to: " +
                              mediaPlayerStatusToString(status))
                switch (status) {
                case MediaPlayer.Loading:
                case MediaPlayer.Buffering:
                case MediaPlayer.Stalled:
                    indicator.running = true
                    break;
                case MediaPlayer.Buffered:
                    indicator.running = false
                    break;
                }
            }

            onPlaybackStateChanged: {
                console.debug("Media Player state changed to: " +
                              mediaPlayerStateToString(playbackState))
                switch (playbackState) {
                case MediaPlayer.PlayingState:
                    indicator.running = false
                    break;
                }
            }

            onPositionChanged: {
                progressBar.setPosition(position)
            }

            onError: {
                console.error(errorString)
                indicator.running = false
            }

            function mediaPlayerStatusToString(status) {
                switch(status) {
                case MediaPlayer.NoMedia: return "NoMedia"
                case MediaPlayer.Loading: return "Loading"
                case MediaPlayer.Loaded: return "Loaded"
                case MediaPlayer.Buffering: return "Buffering"
                case MediaPlayer.Stalled: return "Stalled"
                case MediaPlayer.Buffered: return "Buffered"
                case MediaPlayer.EndOfMedia: return "EndOfMedia"
                case MediaPlayer.InvalidMedia: return "InvalidMedia"
                default: return "UnknownStatus"
                }
            }

            function mediaPlayerStateToString(state) {
                switch(state) {
                case MediaPlayer.PlayingState: return "Playing"
                case MediaPlayer.PausedState: return "Paused"
                case MediaPlayer.StoppedState: return "Stopped"
                }
            }
        }

        GStreamerVideoOutput {
            id: video
            source: mediaPlayer
            anchors.fill: parent

            BusyIndicator {
                id: indicator
                anchors.centerIn: parent
                running: true
                size: BusyIndicatorSize.Large
            }
        }

        MouseArea {
            id: controls
            anchors.fill: parent;

            onClicked: {
                console.debug("Screen tapped, showing video controls")
                show()
            }

            function show() {
                playPauseButton.opacity = 1.0
                progressBar.opacity = 1.0
                controlsTimer.restart()
            }

            function visible() {
                return (playPauseButton.opacity == 1.0);
            }

            Timer {
                id: controlsTimer
                interval: 2500
                repeat: false
                onTriggered: {
                    console.debug("Video controls timeout, hiding")
                    playPauseButtonHide.start()
                    progressBarHide.start()
                }
            }

            Image {
                id: playPauseButton
                anchors.centerIn: parent
                opacity: 0.0
                visible: mediaPlayer.status != MediaPlayer.Stalled
                source: mediaPlayer.playbackState === MediaPlayer.PlayingState ?
                            "image://theme/icon-cover-pause" : "image://theme/icon-cover-play"

                NumberAnimation {
                    id: playPauseButtonHide
                    target: playPauseButton
                    property: "opacity"
                    from: 1.0
                    to: 0.0
                    duration: 500
                    easing.type: Easing.InOutQuad<commit_msg>VideoPlayer: Show Play/Pause button only when progress bar is not visible<commit_after>/*-
 * Copyright (c) 2014 <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of any co-contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.0
import Sailfish.Media 1.0
import "YoutubeClientV3.js" as Yt

Page {
    id: page
    allowedOrientations: Orientation.All
    showNavigationIndicator: page.isPortrait || (page.isLandscape && controls.visible())
    property string videoId
    property string title

    Rectangle {
        id: background;
        anchors.fill: parent
        color: "black"
    }

    SilicaFlickable {
        id: flickable
        anchors.fill: parent

        PageHeader {
            id: header
            title: page.title
            visible: page.isPortrait || (page.isLandscape && controls.visible())
            z: video.z + 2
        }

        // Simple background for PageHeader visible only when player is in landscape mode.
        // It's supposed to ensure header contents are always readeble, no matter what
        // video content is visible in the background.
        Rectangle {
            anchors {
                right: header.right
                left: header.left
                top: header.top
                bottom: header.bottom
            }

            visible: header.visible
            color: "black"
            opacity: 0.5
            z: header.z - 1
        }

        MediaPlayer {
            id: mediaPlayer
            autoPlay: true

            onStatusChanged: {
                console.debug("Media Player status changed to: " +
                              mediaPlayerStatusToString(status))
                switch (status) {
                case MediaPlayer.Loading:
                case MediaPlayer.Buffering:
                case MediaPlayer.Stalled:
                    indicator.running = true
                    break;
                case MediaPlayer.Buffered:
                    indicator.running = false
                    break;
                }
            }

            onPlaybackStateChanged: {
                console.debug("Media Player state changed to: " +
                              mediaPlayerStateToString(playbackState))
                switch (playbackState) {
                case MediaPlayer.PlayingState:
                    indicator.running = false
                    break;
                }
            }

            onPositionChanged: {
                progressBar.setPosition(position)
            }

            onError: {
                console.error(errorString)
                indicator.running = false
            }

            function mediaPlayerStatusToString(status) {
                switch(status) {
                case MediaPlayer.NoMedia: return "NoMedia"
                case MediaPlayer.Loading: return "Loading"
                case MediaPlayer.Loaded: return "Loaded"
                case MediaPlayer.Buffering: return "Buffering"
                case MediaPlayer.Stalled: return "Stalled"
                case MediaPlayer.Buffered: return "Buffered"
                case MediaPlayer.EndOfMedia: return "EndOfMedia"
                case MediaPlayer.InvalidMedia: return "InvalidMedia"
                default: return "UnknownStatus"
                }
            }

            function mediaPlayerStateToString(state) {
                switch(state) {
                case MediaPlayer.PlayingState: return "Playing"
                case MediaPlayer.PausedState: return "Paused"
                case MediaPlayer.StoppedState: return "Stopped"
                }
            }
        }

        GStreamerVideoOutput {
            id: video
            source: mediaPlayer
            anchors.fill: parent

            BusyIndicator {
                id: indicator
                anchors.centerIn: parent
                running: true
                size: BusyIndicatorSize.Large
            }
        }

        MouseArea {
            id: controls
            anchors.fill: parent;

            onClicked: {
                console.debug("Screen tapped, showing video controls")
                show()
            }

            function show() {
                playPauseButton.opacity = 1.0
                progressBar.opacity = 1.0
                controlsTimer.restart()
            }

            function visible() {
                return (playPauseButton.opacity == 1.0);
            }

            Timer {
                id: controlsTimer
                interval: 2500
                repeat: false
                onTriggered: {
                    console.debug("Video controls timeout, hiding")
                    playPauseButtonHide.start()
                    progressBarHide.start()
                }
            }

            Image {
                id: playPauseButton
                anchors.centerIn: parent
                opacity: 0.0
                visible: !indicator.running
                source: mediaPlayer.playbackState === MediaPlayer.PlayingState ?
                            "image://theme/icon-cover-pause" : "image://theme/icon-cover-play"

                NumberAnimation {
                    id: playPauseButtonHide
                    target: playPauseButton
                    property: "opacity"
                    from: 1.0
                    to: 0.0
                    duration: 500
                    easing.type: Easing.InOutQuad
{'fraction_non_alphanumeric': 0.06198497775833151, 'fraction_numerical': 0.0056880332531174796, 'mean_word_length': 1.532594644506002, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2234472', 'n_tokens_mistral': 3373, 'n_tokens_neox': 3034, 'n_words': 1030}