diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 3d0dcea8ca..0000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,32 +0,0 @@ -skip_commits: - files: - - .travis.yml - -environment: - matrix: - - nodejs_version: STABLE - -cache: - - node_modules -> package.json - -build_script: - - yarn config set yarn-offline-mirror ./node_modules/ - - yarn install --ignore-engines --ignore-scripts - - yarn build - -after_build: - - yarn gulp compress - -artifacts: - - path: build\*.zip - name: PopcornTime - -deploy: - description: 'Windows Release' - provider: GitHub - auth_token: - secure: wKYGmYxyZoGANT1qraz3HzsUN9tiYx9pvF3KpILJZ/UQtC+EC5XHsnxKNtCjDUhb # your encrypted token from GitHub - artifact: /build/.*\.zip/ - on: - branch: master - appveyor_repo_tag: false diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f8022b6469..7c72f50175 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,35 +11,34 @@ assignees: '' If you are asking a question rather than filing a bug, try one of these instead: - Wiki & FAQ (https://github.com/popcorn-official/popcorn-desktop/wiki) - Reddit /r/PopCornTimeApp (https://www.reddit.com/r/PopCornTimeApp/) -- Popcorn Time Forum (https://discuss.popcorntime.app/) --> -Operating System Version: - +#### Operating System Version: + -Popcorn Time Version: +#### Popcorn Time Version: -Download date: +#### Download date: -Download url: +#### Download url: -#### Expected Behaviour +#### Expected Behaviour: ... -#### Actual Behaviour +#### Actual Behaviour: ... -#### Steps to reproduce the behaviour +#### Steps to reproduce the behaviour: 1. ... 2. ... 3. ... -#### Screenshot(s) of issue or error(s) logs of developer console (Windows/Linux: F12, MacOS: ⌘ + 0 ... then 'console' tab) (recommended) +#### Screenshot(s) of issue or error(s) logs of developer console (Windows/Linux: F12, MacOS: ⌘ + 0 ... then 'console' tab) (recommended): diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cfb2e76442..a30861d03c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macOS-latest, windows-latest] - nwjs: ['0.44.5', '0.82.0'] + nwjs: ['0.44.5', '0.86.0'] steps: - name: Context @@ -51,26 +51,75 @@ jobs: key: "${{ matrix.os }}" map: | { - "ubuntu-latest": { "platform": "linux", "dist": "linux32,linux64" }, - "macOS-latest": { "platform": "osx", "dist": "osx64" }, - "windows-latest": { "platform": "win", "dist": "win32,win64" } + "ubuntu-latest": { "platform": "linux64" }, + "macOS-latest": { "platform": "osx64" }, + "windows-latest": { "platform": "win64" } } - name: Build info - run: echo Build ${{ env.dist }} on nw-v${{ matrix.nwjs }} + run: echo Build ${{ env.platform }} on nw-v${{ matrix.nwjs }} - name: Build App run: | yarn - yarn gulp dist --platforms=${{ env.platform == 'win' && '"' || '' }}${{ env.dist }}${{ env.platform == 'win' && '"' || '' }} --nwVersion=${{ matrix.nwjs }} + yarn gulp dist --platforms=${{ env.platform == 'win' && '"' || '' }}${{ env.platform }}${{ env.platform == 'win' && '"' || '' }} --nwVersion=${{ matrix.nwjs }} - name: Upload artifacts uses: actions/upload-artifact@master with: name: ${{ env.platform }}-${{ matrix.nwjs }} path: build - release: + packs: needs: build + name: Packs + runs-on: ubuntu-latest + + strategy: + matrix: + nwjs: ['0.44.5', '0.86.0'] + + steps: + - name: Context + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + + - uses: actions/checkout@v4 + with: + path: repo + persist-credentials: false + + - uses: actions/download-artifact@v4 + with: + name: linux64-${{ matrix.nwjs }} + path: . + + - name: Install packages and appimagetool + run: | + sudo apt update + sudo apt install -y libfuse2 + wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage + chmod +x appimagetool-x86_64.AppImage + + - name: Build AppImage + run: | + VER=$(ls *-linux64*.zip | sed 's/-linux64.*//') + echo $VER + unzip -q *-linux64*.zip -d $VER.AppDir + cp repo/dist/linux/appimage/* $VER.AppDir/ + ln -s Popcorn-Time $VER.AppDir/AppRun + mkdir build + ./appimagetool-x86_64.AppImage $VER.AppDir build/$VER-linux64${{ matrix.nwjs == '0.44.5' && '-0.44.5' || '' }}.AppImage + + - name: Upload artifacts + uses: actions/upload-artifact@master + with: + name: linux64-${{ matrix.nwjs }}.AppImage + path: build + + + release: + needs: packs name: Release runs-on: ubuntu-latest steps: diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 730bfc8d1a..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -os: - - linux - - osx - -language: node_js -node_js: - - stable -cache: - yarn: true - directories: - - node_modules -before_install: - - yarn config set yarn-offline-mirror ./node_modules/ - - yarn install --ignore-engines - - yarn build -after_success: - - ls -ltr ./build/ -deploy: - provider: releases - file_glob: true - file: build/Popcorn-Time*.zip - name: Build $(date +'%d.%m.%Y %R') - skip_cleanup: true - on: - repo: popcorn-official/popcorn-desktop - branch: development - tags: false - api-key: - secure: "IxNjbYB5ptBG6yvdTVV5otXxOYUO6L31VRxHAL/3A939MukMM6GUBlr0jcJ2mWzxvhHoo90r3RWT/81qCPH0Mf7oDCWthwuAsX1RtOVC7LinbEeLEX4Lp/To0kC2gn0dBwXSJhakkQZ4alZywRxLzV+TxiF/HYlOLuF+6ZZ5mtv6vNIylxkmaQy/KHV43LYLw7weEHafj3TSpLsKFZw0/Rqw/rKKWCMzMY750HmN0rNb54Hbu9+5zVdNpnfa4ovmdTiB7aOjrr2/Z8LVYdw9+MTipwpYq4Kb2syYjkZiduUshI+ttsyw6T5Hgg0hrAnW3pVZ+HLnxQUw75BnUOoF3rFFEdLA3tGQ1BGf2zRoN10JQae/hBAvagY5Y+55m02IUE1qnOCJ6vrAfMb2a1i4Eu+JUCViMw/ITKEYnGkHWyvZ1uhT3M8WqEUAZWCnNlRz2+UjZD4dXOwQwvYzBG5smDW2H1/Z0XRUJjCGU+G5Gvol4qa7Dsb97d6ezQvtqs//DI80Af0IgQawiBVwMboLlgqUCra6+1WqlwzVk22OznkBR3zJDTqJwNkBrXhzmpy6/y2MiqcsctgMsJHClHHy4CD3PK4LplO1IHs0Ix/QZEN6gBUN3vsJsgZjhUuiPD8p0rsnxeCC8XF7GnhJOnnh6RpzF7ZOs1FjcQ+iEixgMGY=" -notifications: - email: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 031a0af76b..8fc1103433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,35 @@ +## 0.5.1 - Now.. Bring me that Horizon - 16 April 2024 + +New Features: +- Update NW.js runtime to 0.86.0 (0.44.5 still supported as an option for this release) +- Add Always show bookmark over covers option +- Improve local file support adding external players/cast devices +- Add option to rescan external players/cast devices +- Include PATH env. variable when scanning for external players +- Improve Torrent Collection/Seedbox interaction +- Add Linux AppImage + +Bug Fixes: +- Fix native player UI issue when in fullscreen +- Fix Favorites/Watched tabs Anime category +- Fix issue with missing covers when TMDb is inaccessible +- Fix issue with displaying incorrect filters in some instances +- Fix issue with the settings/databases flushing functions +- Tooltip fixes + +Other: +- Replace the old Help screen with the online FAQ +- Update the build system +- Clean up obsolete/unnecessary code +- Update torrent trackers +- Update various modules/dependencies +- Various other small fixes and optimizations + ## 0.5.0 - Mischief Managed - 10 February 2024 New Features: - Update NW.js runtime to 0.82.0 (0.44.5 still supported as an option for this release) +- Add macOS build for Apple Silicon (NW.js 0.82.0 only) - Add working Anime tab - Add Watched tab - Add Seedbox option for exiting the app when downloads complete diff --git a/README.md b/README.md index cf719e03e4..6be80aebb8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@


- Popcorn Time + Popcorn Time
Popcorn Time
@@ -14,15 +14,14 @@ - -
- +
+ + - -

Visit the project's website at popcorntimeapp.netlify.app

+

Visit the project's website at popcorn-time.site

*** @@ -30,13 +29,13 @@ ### Windows: Download and install: - * **Latest release**: check [popcorntimeapp.netlify.app](https://popcorntimeapp.netlify.app) or the repo's [releases page](https://github.com/popcorn-official/popcorn-desktop/releases) + * **Latest release**: check [popcorn-time.site](https://popcorn-time.site) or the repo's [releases page](https://github.com/popcorn-official/popcorn-desktop/releases) * Or **latest dev build (for testers)**: check the repo's [actions page](https://github.com/popcorn-official/popcorn-desktop/actions) ### macOS: Download and install: - * **Latest release**: check [popcorntimeapp.netlify.app](https://popcorntimeapp.netlify.app) or the repo's [releases page](https://github.com/popcorn-official/popcorn-desktop/releases) + * **Latest release**: check [popcorn-time.site](https://popcorn-time.site) or the repo's [releases page](https://github.com/popcorn-official/popcorn-desktop/releases) * Or **latest dev build (for testers)**: check the repo's [actions page](https://github.com/popcorn-official/popcorn-desktop/actions) Easily install Popcorn Time via _[Homebrew](https://brew.sh) ([Cask](https://docs.brew.sh/Cask-Cookbook)):_ @@ -57,7 +56,7 @@ Also, if you keep a [_Brewfile_](https://github.com/Homebrew/homebrew-bundle#usa ### Linux - Debian/Ubuntu based distros: Download and install: - * **Latest release**: check [popcorntimeapp.netlify.app](https://popcorntimeapp.netlify.app) or the repo's [releases page](https://github.com/popcorn-official/popcorn-desktop/releases) + * **Latest release**: check [popcorn-time.site](https://popcorn-time.site) or the repo's [releases page](https://github.com/popcorn-official/popcorn-desktop/releases) * Or **latest dev build (for testers)**: check the repo's [actions page](https://github.com/popcorn-official/popcorn-desktop/actions) Via .deb package: @@ -67,13 +66,13 @@ Via .deb package: Via archive and command line (tested on ubuntu 18.04 and 20.04): 1. Download Popcorn Time archive from the github repo for the **latest release** : - `wget -c https://github.com/popcorn-official/popcorn-desktop/releases/download/v0.5.0/Popcorn-Time-0.5.0-linux64.zip` + `wget -c https://github.com/popcorn-official/popcorn-desktop/releases/download/v0.5.1/Popcorn-Time-0.5.1-linux64.zip` 2. Create popcorn-time folder in /opt/: `sudo mkdir /opt/popcorn-time` 3. Install unzip && dependencies (they should not be always required but some users needed them to make Popcorn Time working): `sudo apt update && sudo apt install unzip libcanberra-gtk-module libgconf-2-4 libatomic1` 4. Extract the zip in /opt/popcorn-time: - `sudo unzip Popcorn-Time-0.5.0-linux64.zip -d /opt/popcorn-time` + `sudo unzip Popcorn-Time-0.5.1-linux64.zip -d /opt/popcorn-time` 5. Create symlink of Popcorn-Time in /usr/bin: `sudo ln -sf /opt/popcorn-time/Popcorn-Time /usr/bin/popcorn-time` 6. Create .desktop file (so the launcher): @@ -111,7 +110,7 @@ If you encounter trouble with the above method, you can try: Optionally, you may simply run `./make_popcorn.sh` if you are on a linux or mac based operating system. -Full instructions & troubleshooting tips can be found in the [Contributing Guide](CONTRIBUTING.md#contributing-to-popcorn-time). +Full instructions & troubleshooting tips can be found in the [Contributing Guide](docs/Contributing.md#contributing-to-popcorn-time). #### Building redistribuable packages/installers: @@ -127,7 +126,7 @@ Redistribuable packages are saved into `build/` subfolder. ## Getting Involved Want to report a bug, request a feature, contribute to or translate Popcorn Time? -Check out our in-depth guide to [Contributing to Popcorn Time](CONTRIBUTING.md#contributing-to-popcorn-time). We need all the help we can get! +Check out our in-depth guide to [Contributing to Popcorn Time](docs/Contributing.md#contributing-to-popcorn-time). We need all the help we can get! You can also join our [community](README.md#community) to keep up-to-date and meet other developers. @@ -135,7 +134,7 @@ You can also join our [community](README.md#community) to keep up-to-date and me ## Community Keep track of Popcorn Time development and community activity. * Read and contribute to the official [Popcorn Time Wiki](https://github.com/popcorn-official/popcorn-desktop/wiki/). - * Join in discussions on the [Popcorn Time Forum](https://discuss.popcorntime.app) and [r/PopCornTimeApp](https://www.reddit.com/r/PopcornTimeApp). + * Join in discussions on [r/PopCornTimeApp](https://www.reddit.com/r/PopcornTimeApp). ## Screenshots diff --git a/dist/linux/appimage/Popcorn-Time.desktop b/dist/linux/appimage/Popcorn-Time.desktop new file mode 100644 index 0000000000..9484d177a8 --- /dev/null +++ b/dist/linux/appimage/Popcorn-Time.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Comment=Watch Movies and TV Shows instantly +Name=Popcorn-Time +Exec=Popcorn-Time %U +Icon=Popcorn-Time +MimeType=application/x-bittorrent;x-scheme-handler/magnet; +StartupNotify=false +Categories=AudioVideo +Type=Application +X-Desktop-File-Install-Version=0.26 + diff --git a/dist/linux/appimage/Popcorn-Time.png b/dist/linux/appimage/Popcorn-Time.png new file mode 100644 index 0000000000..921f38212c Binary files /dev/null and b/dist/linux/appimage/Popcorn-Time.png differ diff --git a/dist/linux/bash-deb-builder.sh b/dist/linux/bash-deb-builder.sh deleted file mode 100644 index cca116a9dc..0000000000 --- a/dist/linux/bash-deb-builder.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/bash -# published under GPL3.0 - -# don't modify this file, see 'package-linux' instead -# requires : build-essential - -. $1 #get information about the package - -version=$(cat ../../package.json | sed '/version/!d' | sed s/\"version\"://g | sed s/\"//g | sed s/\ //g | sed s/,//g) #specific to node-webkit apps - -scriptdir=$(echo $PWD) #bash-deb-builder.sh dir -maindir=$(cd ../.. && echo $PWD) #main dir - -func_series() { - mainseries=$(echo $series | sed "s/ .*//g") - remainingseries=$(echo $series | sed "s/$mainseries //g") -} - -func_name() { - name="${name,,}" #no uppercase - name="$(echo $name | tr ' ' '-')" #no spaces -} - -func_maintainer() { - export DEBEMAIL="$email" - export DEBFULLNAME="$maintainer" -} - -func_dep() { - [[ -z "$dependencies" ]] || [[ "$dependencies" == "none" ]] || [[ "$dependencies" == "null" ]] && dependencies= -} - -func_exclude() { - exclude=$(echo "$exclude" | sed 's/ / **\//g') #globstar hack -} - -func_size() { - size=$(du -s PACKAGE | cut -f1) -} - -func_appfiles() { - echo -e "\n- Copying app files to new directory" #DEBUG - - shopt -s globstar - func_name #transforms unwanted caracters in name entry - - for arch in "32" "64" ; do - [ $arch == "32" ] && files=$(echo $files32 | sed "s/32/$arch/g") - [ $arch == "64" ] && files=$(echo $files64 | sed "s/64/$arch/g") - - mkdir -p PACKAGE/$name-$version/$arch/$installdir/$name - if [[ ! -z $launcher ]] ; then - mkdir -p PACKAGE/$name-$version/$arch/usr/share/applications - echo "$launcher" &> PACKAGE/$name-$version/$arch/usr/share/applications/$name.desktop - chmod 644 PACKAGE/$name-$version/$arch/usr/share/applications/$name.desktop - fi - cp -r $files PACKAGE/$name-$version/$arch/$installdir/$name - cd PACKAGE/$name-$version/$arch/$installdir/$name - func_exclude - rm -rf **/$exclude **/*.*~ &> /dev/null - cd $scriptdir - done -} - -func_modify() { - #changelog - func_series - sed -i "s/unstable/$mainseries/g" changelog - sed -i "s/$version-1/$version/g" changelog - sed -i "s/(Closes: #nnnn) //g" changelog - - #control - sed -i "s/unknown/$section/g" control - sed -i '/Homepage/d' control - sed -i "s//$short_description/g" control - sed -i '/long description/d' control - echo "$long_description" | tee -a control &> /dev/null - echo "Homepage: $homepage" | tee -a control &> /dev/null - func_dep #makes sure that dependencies are well written if empty - sed -i "s/\${shlibs:Depends}/$dependencies/g" control - sed -i '7,8d' control - - #copyrights - echo "$copyright" &> copyright - - #rules - echo "$rules" &> rules - - #post-install and remove script - echo "$postinst" &> postinst - echo "$prerm" &> prerm - sudo chmod 755 post* pre* -} - -func_basefiles() { - echo -e "\n- Creating tar.xz archive" #DEBUG - - cd PACKAGE/$name-$version - tar --xz -cf ../$name"_"$version".orig.tar.xz" * - - echo -e "\n- Creating 'debian' directory" #DEBUG - - dh_make -s -y -c $license -f $name"_"$version".orig.tar.xz" - cd debian && rm -rf *ex *EX README* docs - func_modify #insert modification to changelog, copyright, rules, control, etc. - #TODO:changelog is not detailed. - cd $scriptdir -} - -func_build() { - echo -e "\n- Build with 'dpkg-buildbackage'" #DEBUG - - cd PACKAGE/$name-$version - dpkg-buildpackage -S -rfakeroot -pgpg -k$gpgkey - cd $scriptdir -} - -func_postbuild() { - mv PACKAGE sources"_"$version - rm -rf sources"_"$version/$name-$version -} - -func_upload() { - echo -e "\n- Uploading to $ppa" #DEBUG - - cd sources"_"$version - dput $ppa $name"_"$version"_source.changes" - cd $scriptdir - - echo -e "\n- The package is only listed in '$mainseries'. You might want to go on Launchpad and publish the packages under other series too." #DEBUG -} - -#Exec -rm -rf PACKAGE sources"_"$version #always clean directories -func_maintainer #set environment variables -func_appfiles #adds the program files - -func_basefiles #creates needed files -func_build #create .dsc -func_postbuild #clean working dir and keep sources -[ ! -z $ppa ] && func_upload #uploads to the given PPA. diff --git a/dist/linux/copy-libatomic.sh b/dist/linux/copy-libatomic.sh new file mode 100755 index 0000000000..19f6cebfd3 --- /dev/null +++ b/dist/linux/copy-libatomic.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# launch 'copy-libatomic.sh ' + +builddir=$1 +projectName=$2 +arch=$3 + +outDir="$1/$2/$3" + +sudo dpkg --add-architecture i386 +dpkg-query -s libatomic1 +if [ ! $? = 0 ]; then + sudo apt update + sudo apt install -y libatomic1 +fi +dpkg-query -s libatomic1:i386 +if [ ! $? = 0 ]; then + sudo apt update + sudo apt install -y libatomic1:i386 +fi + +if [[ $arch == "linux64" ]] +then + read source <<< `readlink -f /usr/lib/x86_64*/libatomic.so.*` +else + read source <<< `readlink -f /usr/lib/i386*/libatomic.so.*` +fi +cp $source "$outDir/lib/libatomic.so.1" diff --git a/dist/linux/exec_basefile.sh b/dist/linux/exec_basefile.sh deleted file mode 100644 index 5d709eb37f..0000000000 --- a/dist/linux/exec_basefile.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/bash - -#Error -func_error() { -[ $error == "0" ] && return 0 -echo " -Unexpected Error: -================= -at: $current -... Please try again." -exit 1 -} - -#Get current architecture -current="1:Set architecture" -if [[ $(uname --machine) == "x86_64" ]] ; then - arch="64" && error=0 -elif [[ $(uname --machine) == "i"*"86" ]] ; then - arch="32" && error=0 -else - error=1 -fi -func_error - -#Variables -version="BT_VERSION" -tos="http://butterproject.org/tos.html" - -#Disclaimer -clear -echo " -Butter $version - Linux $arch bits -================================== - -Please read our Terms of service: - $tos - -This installer will install Butter in: - ~/.Butter - ~/.local/share/applications - ~/.local/share/icons -" - -{ read -p "To continue, type 'I agree': " r /dev/null && error=0 || error=1 - -#move icon -mkdir -p "$HOME/.local/share/icons" -cp butter.png "$HOME/.local/share/icons/butter.png" &> /dev/null && error=0 || error=1 - -func_error - -#create .desktop in home -echo " -- Creating new configuration files..." - -current="2: Desktop file" -mkdir -p "$HOME/.local/share/applications" - -echo "[Desktop Entry] -Comment=Watch Movies and TV Shows instantly -Name=Butter -Exec=$HOME/.Butter/Butter -Icon=butter.png -MimeType=application/x-bittorrent;x-scheme-handler/magnet; -StartupNotify=false -Categories=AudioVideo;Video;Network;Player;P2P; -Type=Application" > "$HOME/.local/share/applications/Butter.desktop" && error=0 || error=1 -func_error - -# Work-around for missing libudev.so.1 on Ubuntu 12.04 -if [ ! -e /lib/$(uname --machine)-linux-gnu/libudev.so.1 ]; then - ln -s /lib/$(uname --machine)-linux-gnu/libudev.so.0 $HOME/.Butter/libudev.so.1 - sed -i 's,Exec=,Exec=env LD_LIBRARY_PATH='"$HOME"'/.Butter ,g' $HOME/.local/share/applications/Butter.desktop -fi - -#chmod .desktop -current="3: Chmod files" -chmod +x "$HOME/.Butter/Butter/Butter" &> /dev/null && error=0 || error=1 -chmod +x "$HOME/.local/share/applications/Butter.desktop" &> /dev/null && error=0 || error=1 -func_error - -#uninstaller -echo "How to uninstall Butter ? -=============================== - -1) Main application: -- Delete ~/.Butter -- Delete ~/.local/share/applications/Butter.desktop -- Delete ~/.local/share/icons/butter.png - -2) Configuration files and databases: -- Delete ~/.config/Butter" > "$HOME/.Butter/Uninstall.txt" - -#installation success -echo " - -Butter is now installed in: - «$HOME/.Butter» -" diff --git a/dist/linux/exec_dist_installer.sh b/dist/linux/exec_dist_installer.sh deleted file mode 100644 index bd96075162..0000000000 --- a/dist/linux/exec_dist_installer.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -#remove old script -rm -rf dist/linux/linux-dist-installer - -#copy basefile -cp dist/linux/exec_dist_basefile.sh dist/linux/linux-dist-installer - -#get version from package.json -version=$(cat package.json | sed '/version/!d' | sed s/\"version\"://g | sed s/\"//g | sed s/\ //g | sed s/\ //g | sed s/,//g) - -#write version in script -sed -i "s/BT_VERSION/$version/g" dist/linux/linux-dist-installer diff --git a/dist/linux/exec_installer.sh b/dist/linux/exec_installer.sh deleted file mode 100644 index 09c8f23fb1..0000000000 --- a/dist/linux/exec_installer.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -#remove old script -rm -rf dist/linux/linux-installer - -#copy basefile -cp dist/linux/exec_basefile.sh dist/linux/linux-installer - -#get version from package.json -version=$(cat package.json | sed '/version/!d' | sed s/\"version\"://g | sed s/\"//g | sed s/\ //g | sed s/\ //g | sed s/,//g) - -#write version in script -sed -i "s/BT_VERSION/$version/g" dist/linux/linux-installer diff --git a/dist/linux/package-information b/dist/linux/package-information deleted file mode 100644 index b0d6b10412..0000000000 --- a/dist/linux/package-information +++ /dev/null @@ -1,196 +0,0 @@ -#!/bin/bash -# Package information for bash-deb-builder - -#Project name. Will be transformed with lowercases and replaced with a dash. -name="My Application" - -#Version of *buntu to target. -series="trusty" - -#The required dependencies for your package. Can be empty. -dependencies="thisdep (>= 110) | thatdep (>= 218)" - -#Full name & email of the package maintainer. -maintainer="My Name" -email="myadress@mymail.com" - -#Your public GPG key or the one from your launchpad team. Also known as OpenPGP key. -gpgkey="8 char public key" - -#To automatically upload the archive to a remote PPA. Uncomment to use. -ppa="ppa:owner/name" - -#Project URL if needed, can be empty. -homepage="http://my-website.com" - -#60 char. max. -short_description="My Application is really cool" - -#60 char. max. per line. Always indent with a -long_description=" My Application allows you to use it - for doing things and stuff. - It's a complete application with feature 1 - and feature 2 just for you." - -#The section must exist. If you don't know, choose "misc" -section="web" - -#Where will the package be installed on the user's machine? Currently doesn't work with subdirectories -installdir="/opt" - -#Files to be included in the package -files64="thisfile thatfile" - -files32="thisfile thatfile andthisfiletoo" - -#Files or formats to exclude from the package. Wildcard * allowed. -exclude="this that* *andallofthis*" - -#License tag. Must be: apache|artistic|bsd|gpl|gpl2|gpl3|lgpl|lgpl2|lgpl3|mit -license="gpl3" - -#Launcher for Linux. Will be in a .desktop file. -launcher="[Desktop Entry] -Comment=My App is cool -Name=My Application -Exec=$installdir/my-app/binary -Icon=$installdir/my-app/icon.png -MimeType=application/x-bittorrent;x-scheme-handler/magnet; -StartupNotify=false -Type=Application" - -#Specific rules for Butter -rules="#!/usr/bin/make -f - -DEB_BUILD_GNU_TYPE ?= \$(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) -DEB_HOST_ARCH ?= \$(shell dpkg-architecture -qDEB_HOST_ARCH) -DEB_HOST_ARCH_CPU ?= \$(shell dpkg-architecture -qDEB_HOST_ARCH_CPU) -DEB_HOST_ARCH_OS ?= \$(shell dpkg-architecture -qDEB_HOST_ARCH_OS) -DEB_HOST_GNU_TYPE ?= \$(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) - -configure: configure-stamp -configure-stamp: - dh_testdir - touch configure-stamp - -build: build-arch build-indep - -build-arch: build-stamp -build-indep: build-stamp - -build-stamp: configure-stamp - touch \$@ - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - dh_clean - -install: build - dh_testdir - dh_testroot - dh_prep - dh_installdirs - -ifeq (\$(DEB_HOST_ARCH),amd64) - cp -arf 64/usr \$(CURDIR)/debian/butter/ - cp -arf 64/opt \$(CURDIR)/debian/butter/ -else - cp -arf 32/usr \$(CURDIR)/debian/butter/ - cp -arf 32/opt \$(CURDIR)/debian/butter/ -endif - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_icons - dh_installmenu - dh_link - dh_strip - dh_compress - dh_fixperms - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install" - - -#A text file formatted following http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -copyright="Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: Butter -Source: https://github.com/butterproject/butter-desktop - -Files: * -Copyright: 2014 Butter Project and the contributors -License: GPL-3.0+ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see . - . - On Debian systems, the complete text of the GNU General - Public License version 3 can be found in \"/usr/share/common-licenses/GPL-3\". - -Files: debian/rules -Copyright: 2013 Alin Andrei -License: MIT - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the \"Software\"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - . - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - . - THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE." - -#postinstall script -postinst="#!/bin/sh -set -e - -# Work-around Menu item not being created on first installation -if [ -x /usr/bin/desktop-file-install ]; then - desktop-file-install /usr/share/applications/butter.desktop > /dev/null 2>&1 -fi - -# Work-around for My App not being executable: -if [ -e /opt/my-app/nw ]; then - chmod +x /opt/my-app/binary -fi" - -#pre-remove script -prerm="#!/bin/sh -set -e - -#remove terminal launch -rm -rf /usr/bin/myapp - -#remove symlinked libraries -rm -rf /opt/my-app/libs" diff --git a/casks/popcorn-time.rb b/dist/mac/casks/popcorn-time.rb similarity index 75% rename from casks/popcorn-time.rb rename to dist/mac/casks/popcorn-time.rb index 24dc6b5a02..0a699493c1 100644 --- a/casks/popcorn-time.rb +++ b/dist/mac/casks/popcorn-time.rb @@ -1,12 +1,12 @@ cask "popcorn-time" do - version "0.4.9" + version "0.5.0" nwjs = "0.64.0" arch = "x64" name token.gsub(/\b\w/, &:capitalize) desc "BitTorrent client that includes an integrated media player" - homepage "https://shows.cf/" + homepage "https://github.com/popcorn-official/popcorn-desktop/releases/download/v0.5.0/Popcorn-Time-0.5.0-osx64.zip" repo = "popcorn-official/popcorn-desktop" zip = "#{name.first}-#{version}-osx64.zip" @@ -21,9 +21,9 @@ silent = "silent" end - sha256 "773235cce1ff637e3d1dcf5df02413da2eca2198c1d310cc7a4e78afcc4a38ea" + sha256 "26abc15d95b4afa48d9383f997ed7393bbcc0cca794a6aa8210b3dc468c08b89" - url "#{homepage}/build/#{zip}" + url "https://github.com/popcorn-official/popcorn-desktop/releases/download/v0.5.0/Popcorn-Time-0.5.0-osx64.zip" auto_updates true depends_on arch: :x86_64 diff --git a/CONTRIBUTING.md b/docs/Contributing.md similarity index 100% rename from CONTRIBUTING.md rename to docs/Contributing.md diff --git a/gulpfile.js b/gulpfile.js index 45e7c006ae..9983cdb5b5 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,7 +3,7 @@ /******** * setup * ********/ -const defaultNwVersion = '0.82.0', +const defaultNwVersion = '0.86.0', availablePlatforms = ['linux32', 'linux64', 'win32', 'win64', 'osx64'], releasesDir = 'build', nwFlavor = 'sdk'; @@ -28,7 +28,6 @@ const gulp = require('gulp'), const { detectCurrentPlatform } = require('nw-builder/dist/index.cjs'); -// see: https://shows.cf/version.json const nwVersion = yargs.argv.nwVersion || defaultNwVersion; /*********** @@ -371,14 +370,10 @@ gulp.task('mac-pkg', () => { waitProcess(child).then(() => { console.log('%s pkg packaged in', platform, path.join(process.cwd(), releasesDir)); - if (pkJson.version === curVersion() && !nwSuffix()) { - resolve(); - return; - } return renameFile( path.join(process.cwd(), releasesDir), pkJson.name + '-' + pkJson.version + '.pkg', - pkJson.name + '-' + curVersion() + nwSuffix() + '.pkg' + pkJson.name + '-' + curVersion() + '-osx64' + nwSuffix() + '.pkg' ).then(() => resolve()); }).catch(() => { console.log('%s failed to package pkg', platform); @@ -422,6 +417,22 @@ gulp.task('nwjs', () => { return nw.build(); }) + .then(() => { + return Promise.all( + nw.options.platforms.map((platform) => { + if (platform.indexOf('linux') === -1) { + return null; + } + const child = spawn('bash', [ + 'dist/linux/copy-libatomic.sh', + releasesDir, + pkJson.name, + platform + ]); + return waitProcess(child); + }) + ); + }) .catch(function(error) { console.error(error); }); @@ -584,7 +595,7 @@ gulp.task( 'build', 'compresszip', 'deb', - 'mac-pkg', + // 'mac-pkg', 'nsis', 'cleanForDist', function(done) { diff --git a/package.json b/package.json index b59ccfe89e..49dd51fb9a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "companyName": "Popcorn Time", "installIcon": "./src/app/images/popcorntime.ico", "unInstallIcon": "./src/app/images/butter_uninstall.ico", - "homepage": "https://shows.cf/", + "homepage": "https://popcorn-time.site/", "bugs": "https://github.com/popcorn-official/popcorn-desktop/issues", "repository": { "type": "git", @@ -11,8 +11,8 @@ }, "license": "GPL-3.0", "main": "src/app/index.html", - "version": "0.5.0", - "releaseName": "Mischief Managed", + "version": "0.5.1", + "releaseName": "Now.. Bring me that Horizon", "scripts": { "build": "gulp build", "clean": "gulp clean", @@ -22,7 +22,7 @@ "test": "gulp test", "postinstall": "patch-package" }, - "chromium-args": "--enable-node-worker", + "chromium-args": "--enable-node-worker --no-sandbox", "engines": { "yarn": ">= 1.0.0" }, @@ -73,12 +73,12 @@ "mkdirp": "*", "mousetrap": "~1.6.5", "mv": "2.x.x", + "mime": "^3.0.0", "nedb-promises": "^5.0.3", "node-tvdb": "^4.1.0", "opensubtitles-api": "^5.1.2", "patch-package": "^8.0", "postinstall-postinstall": "^2.1.0", - "q": "2.0.3", "readdirp": "2.x.x", "request": "2.88.x", "rimraf": "^3.0.0", @@ -87,7 +87,7 @@ "send": "^0.17.2", "socks-proxy-agent": "^6.2.1", "srt-to-vtt": "^1.1", - "tar": "4.4.18", + "tar": "6.2.1", "torrentcollection6": "^1.0", "trakt.tv": "7.x.x", "trakt.tv-images": "5.x.x", diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index 6d28c9345a..0000000000 --- a/scripts/release.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -set -e -CURRENT=$(node -p "require('./package.json').version") -echo "Current $CURRENT" -echo "Enter release version: " -read VERSION - -read -p "Releasing $VERSION - are you sure? (y/n)" -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]] -then - git add -A - yarn version --new-version $VERSION - git push origin master - git push origin --tags -fi \ No newline at end of file diff --git a/src/app/app.js b/src/app/app.js index 9bd8bd490f..2b8bd1a8b3 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -144,25 +144,21 @@ App.onBeforeStart = function (options) { // reset app width when the width is bigger than the available width if (screen.availWidth < width) { - win.info('Window too big, resetting width'); width = screen.availWidth; } // reset app height when the width is bigger than the available height if (screen.availHeight < height) { - win.info('Window too big, resetting height'); height = screen.availHeight; } // reset x when the screen width is smaller than the window x-position + the window width if (x < 0 || x + width > screen.width) { - win.info('Window out of view, recentering x-pos'); x = Math.round((screen.availWidth - width) / 2); } // reset y when the screen height is smaller than the window y-position + the window height if (y < 0 || y + height > screen.height) { - win.info('Window out of view, recentering y-pos'); y = Math.round((screen.availHeight - height) / 2); } @@ -194,7 +190,7 @@ var initApp = function () { try { App.showView(mainWindow); } catch (e) { - console.error('Couldn\'t start app: ', e, e.stack); + win.error('Couldn\'t start app: ', e, e.stack); } if (localStorage.maximized === 'true') { @@ -240,7 +236,6 @@ var deleteCookies = function () { if (!result.name) { result = result[0]; } - win.debug('cookie removed: ' + result.name + ' ' + result.url); } else { win.error('cookie removal failed'); } @@ -250,7 +245,6 @@ var deleteCookies = function () { win.cookies.getAll({}, function (cookies) { if (cookies.length > 0) { - win.debug('Removing ' + cookies.length + ' cookies...'); for (var i = 0; i < cookies.length; i++) { removeCookie(cookies[i]); } @@ -446,7 +440,6 @@ window.ondragenter = function (e) { mask.show(); mask.on('dragenter', function (e) { $('.drop-indicator').show(); - win.debug('Drag init'); }); mask.on('dragover', function (e) { var showDrag = true; @@ -457,7 +450,6 @@ window.ondragenter = function (e) { clearTimeout(timeout); timeout = setTimeout(function () { if (!showDrag) { - win.debug('Drag aborted'); $('.drop-indicator').hide(); $('#drop-mask').hide(); } @@ -531,26 +523,37 @@ var isVideo = function (file) { }; var handleVideoFile = function (file) { + var vjsPlayer = document.getElementById('video_player'); + if (vjsPlayer) { + videojs(vjsPlayer).dispose(); + } + App.vent.trigger('settings:close'); + App.vent.trigger('about:close'); + App.vent.trigger('keyboard:close'); + App.vent.trigger('stream:stop'); + App.vent.trigger('player:close'); + App.vent.trigger('torrentcache:stop'); + App.vent.trigger('preload:stop'); $('.spinner').show(); // look for local subtitles var checkSubs = function () { + var _dir = file.path.replace(/\\/g, '/'); + _dir = _dir.substr(0, _dir.lastIndexOf('/')); var _ext = path.extname(file.name); - var toFind = file.path.replace(_ext, '.srt'); - - if (fs.existsSync(path.join(toFind))) { - return { - local: path.join(toFind) - }; - } else { - return null; - } + var _filename = file.name.replace(_ext, ''); + var found = null; + fs.readdirSync(_dir).forEach(file => { + if (file.includes(_filename) && file.endsWith('.srt')) { + return found = { local: path.join(_dir, file) }; + } + }); + return found; }; // get subtitles from provider var getSubtitles = function (subdata) { return new Promise(function (resolve, reject) { - win.debug('Subtitles data request:', subdata); var subtitleProvider = App.Config.getProviderForType('subtitle'); @@ -561,7 +564,6 @@ var handleVideoFile = function (file) { win.info(Object.keys(subs).length + ' subtitles found'); resolve(subs); } else { - win.warn('No subtitles returned'); if (Settings.subtitle_language !== 'none') { App.vent.trigger( 'notification:show', @@ -673,17 +675,16 @@ var handleVideoFile = function (file) { if (localsub !== null) { playObj.defaultSubtitle = 'local'; } else { - playObj.defaultSubtitle = 'none'; + playObj.defaultSubtitle = Settings.subtitle_language; } resolve(playObj); }) .catch(function (err) { - win.warn('trakt.matcher.match error:', err); var localsub = checkSubs(); if (localsub !== null) { playObj.defaultSubtitle = 'local'; } else { - playObj.defaultSubtitle = 'none'; + playObj.defaultSubtitle = Settings.subtitle_language; } if (!playObj.title) { @@ -699,16 +700,34 @@ var handleVideoFile = function (file) { $('.spinner').hide(); var localVideo = new Backbone.Model(play); // streamer model - console.debug( - 'Trying to play local file', - localVideo.get('src'), - localVideo.attributes - ); - var tmpPlayer = App.Device.Collection.selected.attributes.id; - App.Device.Collection.setDevice('local'); - App.vent.trigger('stream:ready', localVideo); // start stream - App.Device.Collection.setDevice(tmpPlayer); + win.info('Loading local file:', localVideo.get('videoFile') || localVideo.get('src')); + + const fileName = localVideo.get('src').replace(/\\/g, '/').split('/').pop(); + var torrentStart = new Backbone.Model({ + torrent: localVideo, + title: fileName, + defaultSubtitle: localVideo.defaultSubtitle || Settings.subtitle_language, + device: App.Device.Collection.selected, + video_file: { + name: fileName, + size: file.size, + index: 0, + path: localVideo.get('src') + }, + files: [{ + name: fileName, + size: file.size, + index: 0, + offset: 0, + length: file.size, + display: true, + done: true, + path: localVideo.get('src') + }] + }); + + App.vent.trigger('stream:start', torrentStart, 'local'); $('.eye-info-player, .maximize-icon #maxdllb').hide(); $('.vjs-load-progress').css('width', '100%'); @@ -721,13 +740,13 @@ var handleTorrent = function (torrent) { } catch (err) { // The player wasn't running } + Settings.importedTorrent = true; App.Config.getProviderForType('torrentCache').resolve(torrent); }; window.ondrop = function (e) { e.preventDefault(); $('#drop-mask').hide(); - console.debug('Drag completed'); $('.drop-indicator').hide(); var file = e.dataTransfer.files[0]; @@ -826,8 +845,6 @@ nw.App.on('open', function (cmd) { } if (file) { - win.debug('File loaded:', file); - if (isVideo(file)) { var fileModel = { path: file, diff --git a/src/app/bootstrap.js b/src/app/bootstrap.js index bda0764eb8..6ddbaede5e 100644 --- a/src/app/bootstrap.js +++ b/src/app/bootstrap.js @@ -3,7 +3,6 @@ App.start(); /* load all the things ! */ - var Q = require('q'); var fs = require('fs'); function loadLocalProviders() { @@ -18,8 +17,6 @@ return null; } - win.info('loading local provider', file); - return new Promise((resolve, reject) => { var script = document.createElement('script'); @@ -28,7 +25,7 @@ script.onload = function() { script.onload = null; - win.info('loaded', file); + win.info('Loaded local provider:', file); resolve(file); }; @@ -41,13 +38,13 @@ } function loadFromNPM(name, fn) { - var P = require(name); - return Q(fn(P)); + const P = require(name); + return Promise.resolve(fn(P)); } function loadProvidersJSON(fn) { return pkJson.providers.map(function(providerPath) { - win.info('loading json', providerPath); + win.info('Loaded provider:', providerPath); return loadFromNPM(`./${providerPath}`, fn); }); } @@ -58,7 +55,7 @@ }); return packages.map(function(name) { - win.info('loading npm', regex, name); + win.info('Loaded npm', regex, name); return loadFromNPM(name, fn); }); } @@ -120,8 +117,5 @@ }); return providers; - }) - .then(function(providers) { - win.info('loaded', providers); }); })(window.App); diff --git a/src/app/common.js b/src/app/common.js index 56522f51d5..866ffbf237 100644 --- a/src/app/common.js +++ b/src/app/common.js @@ -1,317 +1,319 @@ var Common = {}, - torrentHealth = require('webtorrent-health'); + torrentHealth = require('webtorrent-health'); Common.healthMap = { - 0: 'bad', - 1: 'medium', - 2: 'good', - 3: 'excellent' + 0: 'bad', + 1: 'medium', + 2: 'good', + 3: 'excellent' }; Common.calcHealth = function (torrent) { - var seeds = torrent.seed; - var peers = torrent.peer; - - // First calculate the seed/peer ratio - var ratio = peers > 0 ? (seeds / peers) : seeds; - - // Normalize the data. Convert each to a percentage - // Ratio: Anything above a ratio of 5 is good - var normalizedRatio = Math.min(ratio / 5 * 100, 100); - // Seeds: Anything above 30 seeds is good - var normalizedSeeds = Math.min(seeds / 30 * 100, 100); - - // Weight the above metrics differently - // Ratio is weighted 60% whilst seeders is 40% - var weightedRatio = normalizedRatio * 0.6; - var weightedSeeds = normalizedSeeds * 0.4; - var weightedTotal = weightedRatio + weightedSeeds; - - // Scale from [0, 100] to [0, 3]. Drops the decimal places - var scaledTotal = ((weightedTotal * 3) / 100) | 0; - - return scaledTotal; + var seeds = torrent.seed; + var peers = torrent.peer; + // First calculate the seed/peer ratio + var ratio = peers > 0 ? (seeds / peers) : seeds; + // Normalize the data. Convert each to a percentage + // Ratio: Anything above a ratio of 5 is good + var normalizedRatio = Math.min(ratio / 5 * 100, 100); + // Seeds: Anything above 30 seeds is good + var normalizedSeeds = Math.min(seeds / 30 * 100, 100); + // Weight the above metrics differently + // Ratio is weighted 60% whilst seeders is 40% + var weightedRatio = normalizedRatio * 0.6; + var weightedSeeds = normalizedSeeds * 0.4; + var weightedTotal = weightedRatio + weightedSeeds; + // Scale from [0, 100] to [0, 3]. Drops the decimal places + var scaledTotal = ((weightedTotal * 3) / 100) | 0; + return scaledTotal; }; Common.calcRatio = function (seeds, peers) { - if (isNaN(seeds) || isNaN(peers)) { - return NaN; - } - - if (peers > 0) { - return seeds / peers; - } - - return +seeds; + if (isNaN(seeds) || isNaN(peers)) { + return NaN; + } + if (peers > 0) { + return seeds / peers; + } + return +seeds; }; Common.retrieveTorrentHealth = function (torrent, cb) { - const torrentURL = typeof torrent === 'string' - ? torrent - : torrent.magnet || torrent.url || torrent.magnetURI; - - if (!torrentURL) { - cb(new Error('Torrent URL could not be obtained'), null); - } - - // check for 'magnet:?' because api sometimes sends back links, not magnets - if (!torrentURL.startsWith('magnet:?')) { - return cb(new Error('Torrent is not a magnet URL'), null); - } - - torrentHealth( - torrentURL, - { - timeout: 2500, - trackers: Settings.trackers.forced - }, - cb - ); + const torrentURL = typeof torrent === 'string' + ? torrent + : torrent.magnet || torrent.url || torrent.magnetURI; + if (!torrentURL) { + cb(new Error('Torrent URL could not be obtained'), null); + } + // check for 'magnet:?' because api sometimes sends back links, not magnets + if (!torrentURL.startsWith('magnet:?')) { + return cb(new Error('Torrent is not a magnet URL'), null); + } + torrentHealth( + torrentURL, + { + timeout: 2500, + trackers: Settings.trackers.forced + }, + cb + ); }; Common.HealthButton = function (selector, retrieveHealthCallback) { - if (!(this instanceof Common.HealthButton)) { - throw new TypeError('This class must be constructed with "new"'); - } - - const maxChecksWhenNoSeeds = 3; - let zeroSeedCheckCount = 0; - let pendingRender = null; - - const getIcon = () => { - return $(selector); - }; - - this.reset = () => { - getIcon() - .tooltip({ - html: true - }) - .removeClass('Bad Medium Good Excellent') - .addClass('None') - .attr('data-original-title', i18n.__('Health Unknown')) - .tooltip('fixTitle'); - }; - - this.cancelPendingRenders = () => { - if (pendingRender) { - pendingRender.isCancelled = true; - } - }; - - this.render = () => { - // because this is an object, we can keep a ref to it while - // allowing other callers to modify it outside of the current - // scope. this lets us know if anyone outside wants this - // request to be cancelled - const cancellationLock = {isCancelled: false}; - this.cancelPendingRenders(); - pendingRender = cancellationLock; - - retrieveHealthCallback((err, res) => { - if (err || cancellationLock.isCancelled) { - return; - } - - const seeds = Math.max.apply(Math, res.extra.map(function(o) { return o.seeds || 0; })); - const peers = Math.max.apply(Math, res.extra.map(function(o) { return o.peers || 0; })); - win.debug('torrent health:', res); - - if (seeds === 0 && zeroSeedCheckCount < maxChecksWhenNoSeeds) { - zeroSeedCheckCount++; - getIcon().click(); - } else { - zeroSeedCheckCount = 0; - const healthValue = Common.calcHealth({seed: seeds, peer: peers}); - const healthString = Common.healthMap[healthValue].capitalize(); - const ratio = res.ratio || Common.calcRatio(seeds, peers); - - const tooltipPieces = [ - i18n.__(`Health ${healthString}`) - ]; - - if (!isNaN(ratio)) { - tooltipPieces.push(` - ${i18n.__('Ratio:')} ${ratio.toFixed(2)}
`); - } - - if (!isNaN(seeds)) { - tooltipPieces.push(`${i18n.__('Seeds:')} ${seeds}`); - } - - if (!isNaN(peers)) { - tooltipPieces.push(` - ${i18n.__('Peers:')} ${peers}`); - } - - getIcon() - .tooltip({ - html: true - }) - .removeClass('None Bad Medium Good Excellent') - .addClass(healthString) - .attr('data-original-title', tooltipPieces.join('')) - .tooltip('fixTitle'); - - if ($(selector + '~ .tooltip:contains("Health")').is(':visible')) { - getIcon().tooltip('show'); - } - } - }); - }; + if (!(this instanceof Common.HealthButton)) { + throw new TypeError('This class must be constructed with "new"'); + } + const maxChecksWhenNoSeeds = 3; + let zeroSeedCheckCount = 0; + let pendingRender = null; + const getIcon = () => { + return $(selector); + }; + this.reset = () => { + getIcon() + .tooltip({ + html: true + }) + .removeClass('Bad Medium Good Excellent') + .addClass('None') + .attr('data-original-title', i18n.__('Health Unknown')) + .tooltip('fixTitle'); + }; + this.cancelPendingRenders = () => { + if (pendingRender) { + pendingRender.isCancelled = true; + } + }; + this.render = () => { + // because this is an object, we can keep a ref to it while + // allowing other callers to modify it outside of the current + // scope. this lets us know if anyone outside wants this + // request to be cancelled + const cancellationLock = {isCancelled: false}; + this.cancelPendingRenders(); + pendingRender = cancellationLock; + retrieveHealthCallback((err, res) => { + if (err || cancellationLock.isCancelled) { + return; + } + const seeds = Math.max.apply(Math, res.extra.map(function(o) { return o.seeds || 0; })); + const peers = Math.max.apply(Math, res.extra.map(function(o) { return o.peers || 0; })); + if (seeds === 0 && zeroSeedCheckCount < maxChecksWhenNoSeeds) { + zeroSeedCheckCount++; + getIcon().click(); + } else { + zeroSeedCheckCount = 0; + const healthValue = Common.calcHealth({seed: seeds, peer: peers}); + const healthString = Common.healthMap[healthValue].capitalize(); + const ratio = res.ratio || Common.calcRatio(seeds, peers); + const tooltipPieces = [ + i18n.__(`Health ${healthString}`) + ]; + if (!isNaN(ratio)) { + tooltipPieces.push(`  -  ${i18n.__('Ratio:')} ${ratio.toFixed(2)}
`); + } + if (!isNaN(seeds)) { + tooltipPieces.push(`${i18n.__('Seeds:')} ${seeds}`); + } + if (!isNaN(peers)) { + tooltipPieces.push(`  /  ${i18n.__('Peers:')} ${peers}`); + } + getIcon() + .tooltip({ + html: true + }) + .removeClass('None Bad Medium Good Excellent') + .addClass(healthString) + .attr('data-original-title', tooltipPieces.join('')) + .tooltip('fixTitle'); + if ($(selector + '~ .tooltip:contains("Health")').is(':visible')) { + getIcon().tooltip('show'); + } + } + }); + }; }; Common.md5 = function (arg) { - return crypt.createHash('md5').update(arg).digest('hex'); + return crypt.createHash('md5').update(arg).digest('hex'); }; Common.fileSize = function (num) { - if (isNaN(num) || num === null) { - return; - } - - num = parseInt(num); - - var exponent, unit, units, base; - var neg = num < 0; - - switch (os.platform()) { - case 'linux': - base = 1024; - units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; - break; - case 'win32': - base = 1024; - units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - break; - case 'darwin': - /* falls through */ - default: - base = 1000; - units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - } - - if (neg) { - num = -num; - } - - if (num < 1) { - unit = units[0]; - if (Settings.language === 'fr') { - unit = unit.replace('B', 'o'); - } - return (neg ? '-' : '') + num + ' ' + unit; - } - - exponent = Math.min(Math.floor(Math.log(num) / Math.log(base)), units.length - 1); - num = (num / Math.pow(base, exponent)).toFixed(2) * 1; - unit = units[exponent]; - - var matcher = Settings.language.match(/sq|es|hy|az|be|qu|pt|bs|ca|bg|hr|cs|da|et|fo|fi|fr|de|ka|el|hu|is|id|it|kk|lv|lt|mn|nl|nn|nb|no|pl|ro|ru|sr|sk|sl|sv|tr|uk|uz|vi/); - if (matcher !== null) { - num = num.toString().replace('.', ','); - } - if (Settings.language === 'fr') { - unit = unit.replace('B', 'o'); - } - return (neg ? '-' : '') + num + ' ' + unit; + if (isNaN(num) || num === null) { + return; + } + num = parseInt(num); + var exponent, unit, units, base; + var neg = num < 0; + switch (os.platform()) { + case 'linux': + base = 1024; + units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + break; + case 'win32': + base = 1024; + units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + break; + case 'darwin': + /* falls through */ + default: + base = 1000; + units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + } + if (neg) { + num = -num; + } + if (num < 1) { + unit = units[0]; + if (Settings.language === 'fr') { + unit = unit.replace('B', 'o'); + } + return (neg ? '-' : '') + num + ' ' + unit; + } + exponent = Math.min(Math.floor(Math.log(num) / Math.log(base)), units.length - 1); + num = (num / Math.pow(base, exponent)).toFixed(2) * 1; + unit = units[exponent]; + var matcher = Settings.language.match(/sq|es|hy|az|be|qu|pt|bs|ca|bg|hr|cs|da|et|fo|fi|fr|de|ka|el|hu|is|id|it|kk|lv|lt|mn|nl|nn|nb|no|pl|ro|ru|sr|sk|sl|sv|tr|uk|uz|vi/); + if (matcher !== null) { + num = num.toString().replace('.', ','); + } + if (Settings.language === 'fr') { + unit = unit.replace('B', 'o'); + } + return (neg ? '-' : '') + num + ' ' + unit; }; Common.sanitize = function (input) { - function sanitizeString(string) { - return require('sanitizer').sanitize(string); - } - - function sanitizeObject(obj) { - var result = obj; - for (var prop in obj) { - result[prop] = obj[prop]; - if (obj[prop] && (obj[prop].constructor === Object || obj[prop].constructor === Array)) { - result[prop] = sanitizeObject(obj[prop]); - } else if (obj[prop] && obj[prop].constructor === String) { - result[prop] = sanitizeString(obj[prop]); - } - } - return result; - } - - var output = input; - if (input && (input.constructor === Object || input.constructor === Array)) { - output = sanitizeObject(input); - } else if (input && input.constructor === String) { - output = sanitizeString(input); - } - - return output; + function sanitizeString(string) { + return require('sanitizer').sanitize(string); + } + function sanitizeObject(obj) { + var result = obj; + for (var prop in obj) { + result[prop] = obj[prop]; + if (obj[prop] && (obj[prop].constructor === Object || obj[prop].constructor === Array)) { + result[prop] = sanitizeObject(obj[prop]); + } else if (obj[prop] && obj[prop].constructor === String) { + result[prop] = sanitizeString(obj[prop]); + } + } + return result; + } + var output = input; + if (input && (input.constructor === Object || input.constructor === Array)) { + output = sanitizeObject(input); + } else if (input && input.constructor === String) { + output = sanitizeString(input); + } + return output; }; Common.normalize = (function () { - var from = 'ÃÀÁÄÂÈÉËÊÌÍÏÎÒÓÖÔÙÚÜÛãàáäâèéëêìíïîòóöôùúüûÑñÇç'; - var to = 'AAAAAEEEEIIIIOOOOUUUUaaaaaeeeeiiiioooouuuunncc'; - var mapping = {}; - - for (var i = 0, j = from.length; i < j; i++) { - mapping[from.charAt(i)] = to.charAt(i); - } - - return function (str) { - var ret = []; - for (var i = 0, j = str.length; i < j; i++) { - var c = str.charAt(i); - if (mapping.hasOwnProperty(str.charAt(i))) { - ret.push(mapping[c]); - } else { - ret.push(c); - } - } - return ret.join('').replace(/[^\w,'-]/g, ''); - }; + var from = 'ÃÀÁÄÂÈÉËÊÌÍÏÎÒÓÖÔÙÚÜÛãàáäâèéëêìíïîòóöôùúüûÑñÇç'; + var to = 'AAAAAEEEEIIIIOOOOUUUUaaaaaeeeeiiiioooouuuunncc'; + var mapping = {}; + for (var i = 0, j = from.length; i < j; i++) { + mapping[from.charAt(i)] = to.charAt(i); + } + return function (str) { + var ret = []; + for (var i = 0, j = str.length; i < j; i++) { + var c = str.charAt(i); + if (mapping.hasOwnProperty(str.charAt(i))) { + ret.push(mapping[c]); + } else { + ret.push(c); + } + } + return ret.join('').replace(/[^\w,'-]/g, ''); + }; })(); -Common.loadImage = function(img) { - return new Promise(function(resolve, reject) { - let cache = new Image(); - cache.onload = () => { - if (img.indexOf('.gif') !== -1) { - // freeze gifs - let c = document.createElement('canvas'); - let w = (c.width = img.width); - let h = (c.height = img.height); - - c.getContext('2d').drawImage(cache, 0, 0, w, h); - img = c.toDataURL(); - } - resolve(img); - }; - - cache.onerror = () => resolve(null); - cache.src = img; - }); +Common.loadImage = function(img, proxy = false) { + return new Promise(function(resolve, reject) { + let cache = new Image(); + cache.onload = () => { + if (img.indexOf('.gif') !== -1) { + // freeze gifs + let c = document.createElement('canvas'); + let w = (c.width = img.width); + let h = (c.height = img.height); + c.getContext('2d').drawImage(cache, 0, 0, w, h); + img = c.toDataURL(); + } + resolve(img); + }; + cache.onerror = () => { + if (proxy || img.indexOf('image.tmdb.org') === -1) { + resolve(null); + return; + } + const apiUrl = App.Config.getProviderForType('tvshow')[0].apiURL; + const url = apiUrl[0] + 'posters/' + img.split('/').pop(); + resolve(Common.loadImage(url, true)); + }; + cache.src = img; + }); }; Common.Promises = { - allSettled: function (promises) { - var wrappedPromises = promises.map( - p => Promise.resolve(p) - .then(val => ({ok: true, value: val}), err => ({ok: false, reason: err}) - )); - return Promise.all(wrappedPromises); - } + allSettled: function (promises) { + var wrappedPromises = promises.map( + p => Promise.resolve(p) + .then(val => ({ok: true, value: val}), err => ({ok: false, reason: err}) + )); + return Promise.all(wrappedPromises); + } }; Common.getTorrentUri = torrent => torrent.magnet || torrent.url || torrent; Common.openOrClipboardLink = function(e, link, text, noOpen = false, noCopy = false) { - if (e.button === 2 && !noCopy) { - var clipboard = nw.Clipboard.get(); - clipboard.set(link, 'text'); - $('.notification_alert') - .text(i18n.__('The %s was copied to the clipboard', text)) - .fadeIn('fast') - .delay(2500) - .fadeOut('fast') - ; - } - if (e.button === 0 && !noOpen) { - nw.Shell.openExternal(link); - } + if (e.button === 2 && !noCopy) { + var clipboard = nw.Clipboard.get(); + clipboard.set(link, 'text'); + $('.notification_alert') + .text(i18n.__('The %s was copied to the clipboard', text)) + .fadeIn('fast') + .delay(2500) + .fadeOut('fast') + ; + } + if (e.button === 0 && !noOpen) { + nw.Shell.openExternal(link); + } +}; + +Common.selectPlayer = function(e, thisModel) { + var player = $(e.currentTarget).parent('li').attr('id').replace('player-', ''); + thisModel.set('device', player); + if (!player.match(/[0-9]+.[0-9]+.[0-9]+.[0-9]/ig)) { + AdvSettings.set('chosenPlayer', player); + } +}; + +Common.showPlayerList = function() { + App.vent.trigger('notification:show', new App.Model.Notification({ + title: '', + body: i18n.__('Popcorn Time currently supports') + '
' + extPlayerlst + '.

' + i18n.__('There is also support for Chromecast, AirPlay & DLNA devices.'), + type: 'success' + })); +}; + +Common.refreshPlayerList = function (e) { + e.stopPropagation(); + const dropdownToggle = '.' + $(e.currentTarget).parents().eq(4)[0].className + ' .playerchoice'; + $('.playerchoicerefresh').addClass('fa-spin fa-spinner spin').tooltip('hide'); + Promise.all(App.Device.loadDeviceSupport()).then(function(data) { + App.Device.rescan(); + }).then(function() { + setTimeout(() => { + App.Device.ChooserView('#player-chooser').render(); + App.Device.ChooserView('#player-chooser2').render(); + $('.file-selector #watch-now').text(''); + $('.playerchoicerefresh, .playerchoicehelp').tooltip({html: true, delay: {'show': 800,'hide': 100}}); + $(dropdownToggle).click(); + }, 3000); + }); }; Common.qualityCollator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'}); diff --git a/src/app/lib/config.js b/src/app/config.js similarity index 100% rename from src/app/lib/config.js rename to src/app/config.js diff --git a/src/app/css/animation.css b/src/app/css/animation.css deleted file mode 100644 index 9312c73d24..0000000000 --- a/src/app/css/animation.css +++ /dev/null @@ -1,64 +0,0 @@ -#init-content { - width: 100%; - /* Full Width */ - height: 5px; - background: #000; - margin-top: 14%; -} - -.init-expand { - width: 100%; - height: 1px; - margin: 2px 0; - background: #2187e7; - position: absolute; - box-shadow: 0px 0px 10px 1px rgba(0, 198, 255, 0.7); - -moz-animation: fullexpand 10s ease-out; - -webkit-animation: fullexpand 10s ease-out; -} - -/* Full Width Animation Bar */ - -@-webkit-keyframes fullexpand { - 0% { - width: 0px; - } - - 100% { - width: 100%; - } -} - -@-webkit-keyframes spin { - 0% { - -webkit-transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - } -} - -@-webkit-keyframes spinoff { - 0% { - -webkit-transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(-360deg); - } -} - -@keyframes spin { - 0% { - transform: rotate(0deg); - } - - 100% { - transform: rotate(359deg); - } -} - -@keyframes blinker { - 50% { - opacity: 0; - } -} diff --git a/src/app/database.js b/src/app/database.js index d85c7dffb0..6a5962f850 100644 --- a/src/app/database.js +++ b/src/app/database.js @@ -3,7 +3,6 @@ var Datastore = require('nedb-promises'), TTL = 1000 * 60 * 60 * 24; var startupTime = window.performance.now(); -console.debug('Database path: ' + data_path); db.bookmarks = new Datastore({ filename: path.join(data_path, 'data/bookmarks.db'), @@ -93,15 +92,15 @@ var Database = { }, deleteBookmarks: function () { - return db.bookmarks.remove({}, { - multi: true - }); + try { fs.unlinkSync(path.join(data_path, 'data/movies.db')); } catch (error) {} + try { fs.unlinkSync(path.join(data_path, 'data/shows.db')); } catch (error) {} + try { fs.unlinkSync(path.join(data_path, 'data/bookmarks.db')); } catch (error) {} + return Promise.resolve(); }, deleteWatched: function () { - return db.watched.remove({}, { - multi: true - }); + try { fs.unlinkSync(path.join(data_path, 'data/watched.db')); } catch (error) {} + return Promise.resolve(); }, // format: {page: page, keywords: title} @@ -334,9 +333,8 @@ var Database = { }, resetSettings: function () { - return db.settings.remove({}, { - multi: true - }); + try { fs.unlinkSync(path.join(data_path, 'data/settings.db')); } catch (error) {} + return Promise.resolve(); }, applyDhtSettings: function (dhtInfo) { @@ -351,12 +349,10 @@ var Database = { Settings.issuesUrl = dhtInfo.git + 'issues'; Settings.sourceUrl = dhtInfo.git; Settings.commitUrl = dhtInfo.git + 'commit'; - Settings.projectCi = dhtInfo.git + 'actions'; Settings.projectBlog = dhtInfo.git + 'wiki'; } if (dhtInfo.site) { Settings.projectUrl = dhtInfo.site; - dhtInfo.d ? Settings.projectForum2 = dhtInfo.site.split('//')[0] + '//discuss.' + dhtInfo.site.split('//')[1] : null; dhtInfo.s ? Settings.statusUrl = dhtInfo.site.split('//')[0] + '//status.' + dhtInfo.site.split('//')[1] : null; } if (dhtInfo.keys) { @@ -372,17 +368,11 @@ var Database = { }, deleteDatabases: function () { - - fs.unlinkSync(path.join(data_path, 'data/watched.db')); - - fs.unlinkSync(path.join(data_path, 'data/movies.db')); - - fs.unlinkSync(path.join(data_path, 'data/bookmarks.db')); - - fs.unlinkSync(path.join(data_path, 'data/shows.db')); - - fs.unlinkSync(path.join(data_path, 'data/settings.db')); - + try { fs.unlinkSync(path.join(data_path, 'data/watched.db')); } catch (error) {} + try { fs.unlinkSync(path.join(data_path, 'data/movies.db')); } catch (error) {} + try { fs.unlinkSync(path.join(data_path, 'data/bookmarks.db')); } catch (error) {} + try { fs.unlinkSync(path.join(data_path, 'data/shows.db')); } catch (error) {} + try { fs.unlinkSync(path.join(data_path, 'data/settings.db')); } catch (error) {} return Promise.resolve(); }, @@ -449,7 +439,7 @@ var Database = { }) .then(function () { if (AdvSettings.get('disclaimerAccepted')) { - App.DhtReader.updateOld(); + App.Updater.updateDHTOld(); if (Settings.updateNotification) { App.Updater.onlyNotification(); } diff --git a/src/app/dht.js b/src/app/dht.js deleted file mode 100644 index c0bda2764d..0000000000 --- a/src/app/dht.js +++ /dev/null @@ -1,152 +0,0 @@ -'use strict'; - -var DHT = require('bittorrent-dht'); -var ed = require('@noble/ed25519'); // better use ed25519-supercop but need rebuild ed25519 for windows - -class DhtReader { - constructor(options) { - this.options = _.defaults(options || {}, {}); - } - - update(e) { - const self = this; - if (!Settings.dht) { - if (e && e !== 'urls') { - self.alertIcon('error'); - self.alertMessage('error'); - } - return; - } else if (e && e !== 'urls') { - self.alertIcon(); - self.alertMessage('wait'); - } - const dht = new DHT({verify: ed.verify}); - const hash = Buffer(Settings.dht, 'hex'); - dht.once('ready', function () { - dht.get(hash, function (err, node) { - if (err || !node || !node.v) { - if (e && e !== 'urls') { - self.alertIcon('error'); - self.alertMessage('error'); - } - return; - } - let data = AdvSettings.get('dhtData'); - let newData = node.v.toString(); - let info = AdvSettings.get('dhtInfo'); - let newInfo = typeof newData === 'string' ? JSON.parse(newData) : null; - AdvSettings.set('dhtData', newData); - AdvSettings.set('dhtDataUpdated', Date.now()); - if (e !== 'urls'){ - if (e) { - self.alertIcon('success'); - } - AdvSettings.set('dhtInfo', newInfo); - } - if (data !== newData && e !== 'urls') { - self.updateSettings(); - if (!Settings.dhtEnable || (Settings.customMoviesServer || Settings.customSeriesServer || Settings.customAnimeServer)) { - self.alertMessage('change'); - } else { - self.alertMessage('restart'); - } - } else if (e === 'enable') { - self.alertMessage('restart'); - } else if (e === 'manual') { - if (info.toString() !== newInfo.toString()) { - self.alertMessage('restart'); - } else { - self.alertMessage('alrdupdated'); - } - } - }); - }); - } - - updateOld() { - if (!Settings.dht) { - return; - } - let data = AdvSettings.get('dhtData'); - let last = AdvSettings.get('dhtDataUpdated'); - const time = 1000 * 60 * 60 * 24 * 7; - if (!data) { - if (Settings.dhtEnable) { - this.update('enable'); - } else { - this.update('urls'); - } - } else if (Date.now() - last > time) { - this.update(); - } - } - - updateSettings() { - setTimeout(function() { - if (App.ViewStack.includes('settings-container-contain')) { - let scrollPos = $('.settings-container-contain').scrollTop(); - $('.nav-hor.left li:first').click(); - App.vent.trigger('settings:show'); - $('.update-dht').removeClass('fa-spin fa-spinner').addClass('valid-tick'); - $('.settings-container-contain').scrollTop(scrollPos); - } - }, 200); - } - - alertIcon(e) { - if (e) { - let tmpclass = e === 'success' ? 'valid-tick' : 'invalid-cross'; - $('.update-dht').removeClass('fa-spin fa-spinner').addClass(tmpclass); - setTimeout(function() { $('.update-dht').removeClass(tmpclass).addClass('fa-rotate');}, 6000); - } else { - $('.update-dht').removeClass('fa-rotate valid-tick invalid-cross').addClass('fa-spin fa-spinner'); - } - } - - alertMessage(alertType) { - var changeServer = function () { - let newServer = AdvSettings.get('dhtData') && !AdvSettings.get('dhtEnable') ? Settings.dhtInfo.server : ''; - AdvSettings.set('customMoviesServer', newServer); - AdvSettings.set('customSeriesServer', newServer); - AdvSettings.set('customAnimeServer', newServer); - this.alertMessage('restart'); - }.bind(this); - var notificationModel = new App.Model.Notification({ - title: i18n.__('Success'), - showClose: false, - type: 'success', - }); - switch (alertType) { - case 'wait': - notificationModel.set('title', i18n.__('Please wait') + '...'); - notificationModel.set('body', i18n.__('Updating the API Server URLs')); - notificationModel.set('type', 'danger'); - break; - case 'error': - notificationModel.set('title', i18n.__('Error')); - notificationModel.set('body', i18n.__('API Server URLs could not be updated')); - notificationModel.set('type', 'error'); - notificationModel.set('autoclose', true); - break; - case 'change': - notificationModel.set('body', i18n.__('Change API Server(s) to the new URLs?')); - notificationModel.set('buttons', [{ title: '', action: changeServer }, { title: '', action: function () {this.alertMessage('updated');}.bind(this)}]); - break; - case 'restart': - notificationModel.set('body', i18n.__('Please restart your application')); - notificationModel.set('showRestart', true); - notificationModel.set('showClose', true); - break; - case 'updated': - notificationModel.set('body', i18n.__('API Server URLs updated')); - notificationModel.set('autoclose', true); - break; - case 'alrdupdated': - notificationModel.set('body', i18n.__('API Server URLs already updated')); - notificationModel.set('autoclose', true); - } - App.vent.trigger('notification:show', notificationModel); - } -} - -App.DhtReader = new DhtReader(); diff --git a/src/app/fileserver.js b/src/app/fileserver.js new file mode 100644 index 0000000000..aa8a5d04d0 --- /dev/null +++ b/src/app/fileserver.js @@ -0,0 +1,258 @@ +const http = require('http'); +const escapeHtml = require('escape-html'); +const mime = require('mime'); +const pump = require('pump'); +const rangeParser = require('range-parser'); +const queueMicrotask = require('queue-microtask'); +const fs = require('fs'); // we only need fs to get the ReadStream and WriteStream prototypes + +function FileServer (file, opts = {}) { + const server = http.createServer(); + if (!opts.origin) { opts.origin = '*'; } // allow all origins by default + + const sockets = new Set(); + let closed = false; + const _listen = server.listen; + const _close = server.close; + + server.listen = (...args) => { + closed = false; + server.on('connection', onConnection); + server.on('request', onRequest); + return _listen.apply(server, args); + }; + + server.close = cb => { + closed = true; + server.removeListener('connection', onConnection); + server.removeListener('request', onRequest); + _close.call(server, cb); + }; + + server.destroy = cb => { + sockets.forEach(socket => { + socket.destroy(); + }); + + // Only call `server.close` if user has not called it already + if (!cb) { cb = () => {};} + if (closed) { queueMicrotask(cb); } + else { server.close(cb); } + file = null; + }; + + function isOriginAllowed (req) { + // When `origin` option is `false`, deny all cross-origin requests + if (opts.origin === false) return false; + + // Requests without an 'Origin' header are not actually cross-origin, so just + // deny them + if (req.headers.origin == null) return false; + + // The user allowed all origins + if (opts.origin === '*') return true; + + // Allow requests where the 'Origin' header matches the `opts.origin` setting + return req.headers.origin === opts.origin; + } + + function onConnection (socket) { + socket.setTimeout(36000000); + sockets.add(socket); + socket.once('close', () => { + sockets.delete(socket); + }); + } + + function onRequest (req, res) { + // If a 'hostname' string is specified, deny requests with a 'Host' + // header that does not match the origin of the torrent server to prevent + // DNS rebinding attacks. + if (opts.hostname && req.headers.host !== `${opts.hostname}:${server.address().port}`) { + return req.destroy(); + } + + const pathname = new URL(req.url, 'http://example.com').pathname; + + // Allow cross-origin requests (CORS) + if (isOriginAllowed(req)) { + res.setHeader('Access-Control-Allow-Origin', req.headers.origin); + } + + // Prevent browser mime-type sniffing + res.setHeader('X-Content-Type-Options', 'nosniff'); + + // Defense-in-depth: Set a strict Content Security Policy to mitigate XSS + res.setHeader('Content-Security-Policy', "base-uri 'none'; default-src 'none'; frame-ancestors 'none'; form-action 'none';"); + + if (pathname === '/favicon.ico') { + return serve404Page(); + } + + // Allow CORS requests to specify arbitrary headers, e.g. 'Range', + // by responding to the OPTIONS preflight request with the specified + // origin and requested headers. + if (req.method === 'OPTIONS') { + if (isOriginAllowed(req)) return serveOptionsRequest(); + else return serveMethodNotAllowed(); + } + + if (req.method === 'GET' || req.method === 'HEAD') { + return handleRequest(); + } + + return serveMethodNotAllowed(); + + function serveOptionsRequest () { + res.statusCode = 204 // no content + res.setHeader('Access-Control-Max-Age', '600') + res.setHeader('Access-Control-Allow-Methods', 'GET,HEAD') + + if (req.headers['access-control-request-headers']) { + res.setHeader( + 'Access-Control-Allow-Headers', + req.headers['access-control-request-headers'] + ) + } + res.end() + } + + function handleRequest () { + if (pathname === '/') { + return serveIndexPage(); + } + + const index = Number(pathname.split('/')[1]); + if (Number.isNaN(index)) { + return serve404Page(); + } + + serveFile(file); + } + + function serveIndexPage () { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/html'); + + const listHtml = + `
  • + + ${escapeHtml(file.path)} + + (${escapeHtml(file.length)} bytes) +
  • `; + + const html = getPageHTML( + `Local File - WebTorrent`, + ` +

    Local File

    +
      ${listHtml}
    + ` + ); + res.end(html); + } + + function serve404Page () { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/html'); + + const html = getPageHTML( + '404 - Not Found', + '

    404 - Not Found

    ' + ); + res.end(html); + } + + function serveFile (file) { + res.setHeader('Content-Type', mime.getType(file.name) || 'application/octet-stream'); + + // Support range-requests + res.setHeader('Accept-Ranges', 'bytes'); + + // Set name of file (for "Save Page As..." dialog) + res.setHeader( + 'Content-Disposition', + `inline; filename*=UTF-8''${encodeRFC5987(file.name)}` + ); + + // Support DLNA streaming + res.setHeader('transferMode.dlna.org', 'Streaming'); + res.setHeader( + 'contentFeatures.dlna.org', + 'DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000' + ); + + // `rangeParser` returns an array of ranges, or an error code (number) if + // there was an error parsing the range. + let range = rangeParser(file.length, req.headers.range || ''); + + if (Array.isArray(range)) { + res.statusCode = 206 // indicates that range-request was understood + + // no support for multi-range request, just use the first range + range = range[0] + + res.setHeader( + 'Content-Range', + `bytes ${range.start}-${range.end}/${file.length}` + ) + res.setHeader('Content-Length', range.end - range.start + 1) + } else { + res.statusCode = 200 + range = null + res.setHeader('Content-Length', file.length) + } + + if (req.method === 'HEAD') { + return res.end() + } + + pump(fs.createReadStream(file.path, range), res); + } + + function serveMethodNotAllowed () { + res.statusCode = 405 + res.setHeader('Content-Type', 'text/html') + const html = getPageHTML( + '405 - Method Not Allowed', + '

    405 - Method Not Allowed

    ' + ) + res.end(html) + } + } + + return server +} + +// NOTE: Arguments must already be HTML-escaped +function getPageHTML (title, pageHtml) { + return ` + + + + + ${title} + + + ${pageHtml} + + + `; +} + +// From https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent +function encodeRFC5987 (str) { + return encodeURIComponent(str) + // Note that although RFC3986 reserves "!", RFC5987 does not, + // so we do not need to escape it + .replace(/['()]/g, escape) // i.e., %27 %28 %29 + .replace(/\*/g, '%2A') + // The following are not required for percent-encoding per RFC5987, + // so we can allow for a little better readability over the wire: |`^ + .replace(/%(?:7C|60|5E)/g, unescape); +} + +module.exports = FileServer diff --git a/src/app/global.js b/src/app/global.js index 2ea77f5782..46682ccf62 100644 --- a/src/app/global.js +++ b/src/app/global.js @@ -2,7 +2,6 @@ var _ = require('underscore'), async = require('async'), inherits = require('util').inherits, - Q = require('q'), // Machine readable os = require('os'), dayjs = require('dayjs'), diff --git a/src/app/httpapi.js b/src/app/httpapi.js index fb239a81f8..fdfeb5ebce 100644 --- a/src/app/httpapi.js +++ b/src/app/httpapi.js @@ -13,7 +13,7 @@ } var initServer = function () { - return Q.Promise(function (resolve, reject) { + return new Promise(function (resolve, reject) { server = rpc.Server({ 'headers': { // allow custom headers is empty by default 'Access-Control-Allow-Origin': '*' @@ -36,14 +36,12 @@ //Do a small delay before sending data in case there are more simultaneous events var reinitTimeout = function () { - win.debug('HttpAPI: reinitTimeout'); //Only do a delay if the request won't time out in the meantime if (startTime + 8000 - (new Date()).getTime() > 250) { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(emitEvents, 200); - win.debug('HttpAPI: setTimeout'); } }; diff --git a/src/app/images/events/aprilsfool.png b/src/app/images/icons/events/aprilsfool.png similarity index 100% rename from src/app/images/events/aprilsfool.png rename to src/app/images/icons/events/aprilsfool.png diff --git a/src/app/images/events/halloween.png b/src/app/images/icons/events/halloween.png similarity index 100% rename from src/app/images/events/halloween.png rename to src/app/images/icons/events/halloween.png diff --git a/src/app/images/events/newyear.png b/src/app/images/icons/events/newyear.png similarity index 100% rename from src/app/images/events/newyear.png rename to src/app/images/icons/events/newyear.png diff --git a/src/app/images/events/pt_anniv.png b/src/app/images/icons/events/pt_anniv.png similarity index 100% rename from src/app/images/events/pt_anniv.png rename to src/app/images/icons/events/pt_anniv.png diff --git a/src/app/images/events/stpatrick.png b/src/app/images/icons/events/stpatrick.png similarity index 100% rename from src/app/images/events/stpatrick.png rename to src/app/images/icons/events/stpatrick.png diff --git a/src/app/images/events/stvalentine.png b/src/app/images/icons/events/stvalentine.png similarity index 100% rename from src/app/images/events/stvalentine.png rename to src/app/images/icons/events/stvalentine.png diff --git a/src/app/images/events/xmas.png b/src/app/images/icons/events/xmas.png similarity index 100% rename from src/app/images/events/xmas.png rename to src/app/images/icons/events/xmas.png diff --git a/src/app/images/icons/extratorrent-dark.png b/src/app/images/icons/extratorrent-dark.png deleted file mode 100644 index 29ebd0cc86..0000000000 Binary files a/src/app/images/icons/extratorrent-dark.png and /dev/null differ diff --git a/src/app/images/icons/extratorrent-light.png b/src/app/images/icons/extratorrent-light.png deleted file mode 100644 index db10ee8cf9..0000000000 Binary files a/src/app/images/icons/extratorrent-light.png and /dev/null differ diff --git a/src/app/images/icons/extratorrent.png b/src/app/images/icons/extratorrent.png deleted file mode 100644 index db10ee8cf9..0000000000 Binary files a/src/app/images/icons/extratorrent.png and /dev/null differ diff --git a/src/app/images/flags/none.svg b/src/app/images/icons/flag-none.svg similarity index 100% rename from src/app/images/flags/none.svg rename to src/app/images/icons/flag-none.svg diff --git a/src/app/images/flags/question.svg b/src/app/images/icons/flag-question.svg similarity index 100% rename from src/app/images/flags/question.svg rename to src/app/images/icons/flag-question.svg diff --git a/src/app/images/icons/getstrike.png b/src/app/images/icons/getstrike.png deleted file mode 100644 index 95d94c9a96..0000000000 Binary files a/src/app/images/icons/getstrike.png and /dev/null differ diff --git a/src/app/images/icons/icon-discourse.png b/src/app/images/icons/icon-discourse.png index d844688fc0..aa5d0d162c 100644 Binary files a/src/app/images/icons/icon-discourse.png and b/src/app/images/icons/icon-discourse.png differ diff --git a/src/app/images/icons/icon-facebook.png b/src/app/images/icons/icon-facebook.png deleted file mode 100644 index 929b4b17ae..0000000000 Binary files a/src/app/images/icons/icon-facebook.png and /dev/null differ diff --git a/src/app/images/icons/icon-gitlab.png b/src/app/images/icons/icon-gitlab.png deleted file mode 100644 index a1986165d9..0000000000 Binary files a/src/app/images/icons/icon-gitlab.png and /dev/null differ diff --git a/src/app/images/icons/icon-google.png b/src/app/images/icons/icon-google.png deleted file mode 100644 index 01a729d2ca..0000000000 Binary files a/src/app/images/icons/icon-google.png and /dev/null differ diff --git a/src/app/images/icons/icon-stash.png b/src/app/images/icons/icon-stash.png deleted file mode 100644 index 5109bbca1f..0000000000 Binary files a/src/app/images/icons/icon-stash.png and /dev/null differ diff --git a/src/app/images/icons/icon-twitter.png b/src/app/images/icons/icon-twitter.png deleted file mode 100644 index e3ca075957..0000000000 Binary files a/src/app/images/icons/icon-twitter.png and /dev/null differ diff --git a/src/app/images/icons/kickasstorrents.png b/src/app/images/icons/kickasstorrents.png deleted file mode 100644 index a55adb187e..0000000000 Binary files a/src/app/images/icons/kickasstorrents.png and /dev/null differ diff --git a/src/app/images/icons/Player/Sound0.png b/src/app/images/icons/player/Sound0.png similarity index 100% rename from src/app/images/icons/Player/Sound0.png rename to src/app/images/icons/player/Sound0.png diff --git a/src/app/images/icons/Player/Sound1.png b/src/app/images/icons/player/Sound1.png similarity index 100% rename from src/app/images/icons/Player/Sound1.png rename to src/app/images/icons/player/Sound1.png diff --git a/src/app/images/icons/Player/Sound2.png b/src/app/images/icons/player/Sound2.png similarity index 100% rename from src/app/images/icons/Player/Sound2.png rename to src/app/images/icons/player/Sound2.png diff --git a/src/app/images/icons/Player/Sound3.png b/src/app/images/icons/player/Sound3.png similarity index 100% rename from src/app/images/icons/Player/Sound3.png rename to src/app/images/icons/player/Sound3.png diff --git a/src/app/images/icons/Player/Subtitles.png b/src/app/images/icons/player/Subtitles.png similarity index 100% rename from src/app/images/icons/Player/Subtitles.png rename to src/app/images/icons/player/Subtitles.png diff --git a/src/app/images/icons/tpb-dark.png b/src/app/images/icons/tpb-dark.png deleted file mode 100644 index 30f2cfb6c5..0000000000 Binary files a/src/app/images/icons/tpb-dark.png and /dev/null differ diff --git a/src/app/images/icons/tpb-light.png b/src/app/images/icons/tpb-light.png deleted file mode 100644 index 4e03e45504..0000000000 Binary files a/src/app/images/icons/tpb-light.png and /dev/null differ diff --git a/src/app/index.html b/src/app/index.html index 8e8aa98713..02df810acd 100644 --- a/src/app/index.html +++ b/src/app/index.html @@ -7,19 +7,16 @@ -
    - - - - - - + + + + @@ -35,8 +32,7 @@ - - + @@ -44,6 +40,7 @@ + @@ -60,9 +57,9 @@ + - @@ -70,23 +67,15 @@ - + - - + + - - - - - - - - @@ -109,39 +98,33 @@ - - + - + + - - - - + + + + + - - - - - - - diff --git a/src/app/lib/jquery.plugins.js b/src/app/jquery.plugins.js similarity index 100% rename from src/app/lib/jquery.plugins.js rename to src/app/jquery.plugins.js diff --git a/src/app/language/en.json b/src/app/language/en.json index 11065bec05..d7616f7e0a 100644 --- a/src/app/language/en.json +++ b/src/app/language/en.json @@ -586,5 +586,12 @@ "Low": "Low", "Medium": "Medium", "High": "High", - "Very High": "Very High" + "Very High": "Very High", + "Always show bookmark over covers": "Always show bookmark over covers", + "Reset all": "Reset all", + "We are resetting all databases and settings": "We are resetting all databases and settings", + "Resetting settings...": "Resetting settings...", + "Rename": "Rename", + "Refresh": "Refresh", + "Help": "Help" } diff --git a/src/app/lib/device/airplay.js b/src/app/lib/device/airplay.js index ece8f63c0e..da6c4af14d 100644 --- a/src/app/lib/device/airplay.js +++ b/src/app/lib/device/airplay.js @@ -2,27 +2,26 @@ 'use strict'; var airplayer = require('airplayer'), - list = airplayer(), netw = require('network-address'), collection = App.Device.Collection; - var makeID = function (baseID) { - return 'airplay-' + baseID.replace('.', ''); - }; - - var Airplay = App.Device.Generic.extend({ - defaults: { - type: 'airplay', - typeFamily: 'external' - }, - makeID: makeID, - initialize: function (attrs) { + class Airplay extends App.Device.Loaders.Device { + constructor(attrs) { + super(Object.assign( { + type: 'airplay', + typeFamily: 'external' + }, attrs)); + } + makeID(baseID) { + return 'airplay-' + baseID.replace('.', ''); + } + initialize(attrs) { this.device = attrs.device; this.attributes.id = this.makeID(this.device.host); this.attributes.name = this.device.name || this.device.serverInfo.model; this.attributes.address = netw(); - }, - play: function (streamModel) { + } + play(streamModel) { var url = streamModel.attributes.src; this.device.play(url, function (err, res) { if (err) { @@ -30,28 +29,29 @@ } }); - }, - stop: function () { + } + stop() { this.device.destroy(); - }, - pause: function () { + } + pause() { this.device.pause(); - }, - unpause: function () { + } + unpause() { this.device.resume(); } - }); - - list.on('update', function (player) { - win.info('Found A Device Device: %s at %s', player.name, player.host); - collection.add(new Airplay({ - device: player - })); - }); + static scan() { + airplayer().on('update', function (player) { + win.info('Found A Device Device: %s at %s', player.name, player.host); + collection.add(new Airplay({ + device: player + })); + }); + win.info('Scanning: Local Network for Airplay devices'); + } + } - win.info('Scanning: Local Network for Airplay devices'); - App.Device.Airplay = Airplay; + App.Device.Loaders.Airplay = Airplay; })(window.App); diff --git a/src/app/lib/device/chromecast.js b/src/app/lib/device/chromecast.js index 836cf11381..f2d8315bba 100644 --- a/src/app/lib/device/chromecast.js +++ b/src/app/lib/device/chromecast.js @@ -5,25 +5,27 @@ client = new ChromecastAPI(), collection = App.Device.Collection; - var Chromecast = App.Device.Generic.extend({ - defaults: { - type: 'chromecast', - typeFamily: 'external' - }, + class Chromecast extends App.Device.Loaders.Device { + constructor(attrs) { + super(Object.assign( { + type: 'chromecast', + typeFamily: 'external' + }, attrs)); + } - _makeID: function (baseID) { + _makeID (baseID) { return 'chromecast-' + Common.md5(baseID); - }, + } - initialize: function (attrs) { + initialize(attrs) { this.device = attrs.device; this.attributes.id = this._makeID(this.device.name); this.attributes.name = this.device.friendlyName; this.attributes.address = this.device.host; this.updatingSubtitles = false; - }, + } - play: function (streamModel) { + play(streamModel) { var self = this; var url = streamModel.get('src'); @@ -76,9 +78,9 @@ }); }); }); - }, + } - createMedia: function(streamModel, useLocalSubtitle) { + createMedia(streamModel, useLocalSubtitle) { var subtitle = streamModel.get('subtitle'); var cover = streamModel.get('backdrop'); @@ -124,14 +126,13 @@ } return media; - }, + } - pause: function () { + pause() { this.get('device').pause(function () {}); - }, + } - stop: function () { - win.info('Closing Chromecast Casting'); + stop() { App.vent.off('videojs:drop_sub'); App.vent.trigger('stream:stop'); App.vent.trigger('player:close'); @@ -140,40 +141,37 @@ // Also stops player and closes connection. device.stop(function () { device.removeAllListeners(); - win.info('Chromecast: stopped. Listeners removed!'); }); device.close(); //Back to ChromeCast home screen instead of black screen App.vent.trigger('stream:unserve_subtitles'); - }, + } - seekPercentage: function (percentage) { - win.info('Chromecast: seek percentage %s%', percentage.toFixed(2)); + seekPercentage(percentage) { var newCurrentTime = this.get('loadedMedia').duration / 100 * percentage; this.get('device').seekTo(newCurrentTime); - }, + } - forward: function () { + forward() { this.get('device').seek(30); - }, + } - backward: function () { + backward() { this.get('device').seek(-30); - }, + } - unpause: function () { + unpause() { this.get('device').resume(function () {}); - }, + } - updateStatus: function () { + updateStatus() { var self = this; client.on('status', function (status) { - console.log(status); self._internalStatusUpdated(status); }); - }, + } - _internalStatusUpdated: function (status) { + _internalStatusUpdated(status) { if (status.media === undefined) { status.media = this.get('loadedMedia'); } @@ -183,16 +181,18 @@ App.vent.trigger('device:status', status); } } - }); - - win.info('Scanning: Local Network for Chromecast devices'); - client.update(); - client.on('device', function (player) { - win.info('Found Chromecast Device: %s at %s', player.friendlyName, player.host); - collection.add(new Chromecast({ - device: player - })); - }); - - App.Device.Chromecast = Chromecast; + + static scan() { + win.info('Scanning: Local Network for Chromecast devices'); + client.update(); + client.on('device', function (player) { + win.info('Found Chromecast Device: %s at %s', player.friendlyName, player.host); + collection.add(new Chromecast({ + device: player + })); + }); + } + } + + App.Device.Loaders.Chromecast = Chromecast; })(window.App); diff --git a/src/app/lib/device/dlna.js b/src/app/lib/device/dlna.js index 76e125170f..2423eed06d 100644 --- a/src/app/lib/device/dlna.js +++ b/src/app/lib/device/dlna.js @@ -4,24 +4,25 @@ var collection = App.Device.Collection; - var makeID = function(baseID) { - return 'dlna-' + baseID.replace('-', ''); - }; - - var Dlna = App.Device.Generic.extend({ - defaults: { - type: 'dlna', - typeFamily: 'external' - }, - makeID: makeID, - - initialize: function(attrs) { + class Dlna extends App.Device.Loaders.Device { + constructor(attrs) { + super(Object.assign({ + type: 'dlna', + typeFamily: 'external' + }, attrs)); + } + + makeID(baseID) { + return 'dlna-' + baseID.replace('-', ''); + } + + initialize(attrs) { this.player = attrs.player; this.attributes.name = this.player.name; this.attributes.address = this.player.host; - }, + } - play: function(streamModel) { + play(streamModel) { var url = streamModel.get('src'); var self = this; var media; @@ -54,61 +55,52 @@ this.player.on('status', function(status) { self._internalStatusUpdated(status); }); - }, + } - stop: function() { + stop() { this.player.stop(); - }, + } - pause: function() { + pause() { this.player.pause(); - }, + } - forward: function() { + forward() { this.player.seek(30); - }, + } - backward: function() { + backward() { this.player.seek(-30); - }, + } - seek: function(seconds) { - win.info('DLNA: seek %s', seconds); + seek(seconds) { this.get('player').seek(seconds, function(err, status) { - if (err) { - win.error('DLNA.seek:Error', err); - } }); - }, - seekTo: function(newCurrentTime) { - win.info('DLNA: seek to %ss', newCurrentTime); + } + seekTo(newCurrentTime) { this.get('player').seek(newCurrentTime, function(err, status) { - if (err) { - win.error('DLNA.seek:Error', err); - } }); - }, + } - seekPercentage: function(percentage) { - win.info('DLNA: seek percentage %s%', percentage.toFixed(2)); + seekPercentage(percentage) { var newCurrentTime = this.player._status.duration / 100 * percentage; this.seekTo(newCurrentTime.toFixed()); - }, + } - unpause: function() { + unpause() { this.player.play(); - }, - updateStatus: function() { + } + updateStatus() { var self = this; this.get('player').status(function(err, status) { if (err) { - return win.info('DLNA.updateStatus:Error', err); + return win.error('DLNA.updateStatus:Error', err); } self._internalStatusUpdated(status); }); - }, + } - _internalStatusUpdated: function(status) { + _internalStatusUpdated(status) { if (status === undefined) { status = this.player._status; } @@ -117,24 +109,24 @@ App.vent.trigger('device:status', status); } } - }); - - - dlnacasts.on('update', function(player) { - if (collection.where({ - id: player.host - }).length === 0) { - win.info('Found DLNA Device: %s at %s', player.name, player.host); - collection.add(new Dlna({ - id: player.host, - player: player - })); - } - }); - win.info('Scanning: Local Network for DLNA devices'); - dlnacasts.update(); + static scan() { + dlnacasts.on('update', function(player) { + if (collection.where({ + id: player.host + }).length === 0) { + win.info('Found DLNA Device: %s at %s', player.name, player.host); + collection.add(new Dlna({ + id: player.host, + player: player + })); + } + }); + win.info('Scanning: Local Network for DLNA devices'); + dlnacasts.update(); + } + } - App.Device.Dlna = Dlna; + App.Device.Loaders.Dlna = Dlna; })(window.App); diff --git a/src/app/lib/device/ext-player.js b/src/app/lib/device/ext_player.js similarity index 64% rename from src/app/lib/device/ext-player.js rename to src/app/lib/device/ext_player.js index 0047996033..22d44c36b8 100644 --- a/src/app/lib/device/ext-player.js +++ b/src/app/lib/device/ext_player.js @@ -113,7 +113,17 @@ } }; - extPlayerlst = Object.getOwnPropertyNames(players).join(', ').replace(/MPC-HC64, |MPC-BE64, |Mini64/gi, '').replace('Extended', 'Ext.').replace('mpvnet', 'mpv.net').replace(/,([^,]*)$/, ' & $1'); + /* map name back into the object as we use it in match */ + _.each(players, function (v, k) { + players[k].name = k; + }); + + extPlayerlst = Object.getOwnPropertyNames(players).join(', ') + .replace(/MPC-HC64, |MPC-BE64, |Mini64/gi, '') + .replace('Extended', 'Ext.') + .replace('mpvnet', 'mpv.net') + .replace(/,([^,]*)$/, ' &$1') + ; function getPlayerName(loc) { return path.basename(loc).replace(path.extname(loc), ''); @@ -149,13 +159,15 @@ return players[name].fs || ''; } - var ExtPlayer = App.Device.Generic.extend({ - defaults: { - type: 'ext-app', - name: i18n.__('External Player'), - }, + class ExtPlayer extends App.Device.Loaders.Device { + constructor(attrs) { + super(Object.assign({ + type: 'ext-app', + name: i18n.__('External Player'), + }, attrs)); + } - play: function (streamModel) { + play(streamModel) { // "" So it behaves when spaces in path var cmd = '', cmdPath = '', cmdSwitch = '', cmdSub = '', cmdFs = '', cmdFilename = '', cmdUrl = ''; var url = streamModel.attributes.src; @@ -172,7 +184,6 @@ var dataBuff = fs.readFileSync(subtitle); //var targetEncodingCharset = 'utf8'; var detectedEncoding = charsetDetect.detect(dataBuff).encoding; - win.debug('Subtitles charset detected: %s', detectedEncoding); if (detectedEncoding.toLowerCase() === 'utf-8') { cmdSub += '-utf8 '; } @@ -206,100 +217,93 @@ App.vent.trigger('stream:stop'); App.vent.trigger('preload:stop'); }); - }, - - pause: function () {}, + } - stop: function () {}, + pause() {} - unpause: function () {} - }); + stop() {} - /* map name back into the object as we use it in match */ - _.each(players, function (v, k) { - players[k].name = k; - }); + unpause() {} - var searchPaths = { - linux: [], - darwin: [], - win32: [] - }; + static scan() { + let searchPaths = [] - var addPath = function (path) { - if (fs.existsSync(path)) { - searchPaths[process.platform].push(path); - } - }; + let addPath = function (path) { + if (fs.existsSync(path)) { + searchPaths.push(path); + } + }; - // linux - addPath('/usr/bin'); - addPath('/usr/local/bin'); - addPath('/snap/bin'); - addPath('/var/lib/flatpak/app/org.videolan.VLC/current/active'); //Fedora Flatpak VLC Dir - addPath(process.env.HOME + '/.nix-profile/bin'); // NixOS - addPath('/run/current-system/sw/bin'); // NixOS - // darwin - addPath('/Applications'); - addPath(process.env.HOME + '/Applications'); - // win32 - addPath(process.env.SystemDrive + '\\Program Files\\'); - addPath(process.env.SystemDrive + '\\Program Files (x86)\\'); - addPath(process.env.LOCALAPPDATA + '\\Apps\\2.0\\'); + switch (process.platform) { + case 'linux': + process.env.PATH.split(path.delimiter).forEach(addPath); + addPath('/snap/bin'); + addPath('/var/lib/flatpak/app/org.videolan.VLC/current/active'); //Fedora Flatpak VLC Dir + addPath(process.env.HOME + '/.nix-profile/bin'); // NixOS + addPath('/run/current-system/sw/bin'); // NixOS + break; + case 'darwin': + process.env.PATH.split(path.delimiter).forEach(addPath); //for brew + addPath('/Applications'); + addPath(process.env.HOME + '/Applications'); + break; + case 'win32': + addPath(process.env.SystemDrive + '\\Program Files\\'); + addPath(process.env.SystemDrive + '\\Program Files (x86)\\'); + addPath(process.env.LOCALAPPDATA + '\\Apps\\2.0\\'); + break; + } - var folderName = ''; - var birthtimes = {}; + var birthtimes = {}; - async.each(searchPaths[process.platform], function (folderName, pathcb) { - folderName = path.resolve(folderName); - win.info('Scanning: ' + folderName); - var appIndex = -1; - var fileStream = readdirp({ - root: folderName, - depth: 3 - }); - fileStream.on('data', function (d) { - var app = d.name.replace('.app', '').replace('.exe', '').toLowerCase(); - var match = _.filter(players, function (v, k) { - return k.toLowerCase() === app; - }); + async.each(searchPaths, function (folderName, pathcb) { + folderName = path.resolve(folderName); + win.info('Scanning: ' + folderName); + var fileStream = readdirp({ + root: folderName, + depth: 3 + }); + fileStream.on('data', function (d) { + var app = d.name.replace('.app', '').replace('.exe', '').toLowerCase(); + var match = _.filter(players, function (v, k) { + return k.toLowerCase() === app; + }); - if (match.length) { - match = match[0]; - var birthtime = d.stat.birthtime; - var previousBirthTime = birthtimes[match.name]; - if (!previousBirthTime || birthtime > previousBirthTime) { - if (!previousBirthTime) { - collection.add(new ExtPlayer({ - id: match.name, - type: 'external-' + match.type, - name: match.name, - path: d.fullPath - })); - win.info('Found External Player: ' + match.name + ' in ' + d.fullParentDir); - } else { - collection.findWhere({ - id: match.name - }).set('path', d.fullPath); - win.info('Updated External Player: ' + app + ' with more recent version found in ' + d.fullParentDir); + if (match.length) { + match = match[0]; + var birthtime = d.stat.birthtime; + var previousBirthTime = birthtimes[match.name]; + if (!previousBirthTime || birthtime > previousBirthTime) { + if (!previousBirthTime) { + collection.add(new ExtPlayer({ + id: match.name, + type: 'external-' + match.type, + name: match.name, + path: d.fullPath + })); + win.info('Found External Player: ' + match.name + ' in ' + d.fullParentDir); + } else { + collection.findWhere({ + id: match.name + }).set('path', d.fullPath); + win.info('Updated External Player: ' + app + ' with more recent version found in ' + d.fullParentDir); + } + birthtimes[match.name] = birthtime; + } } - birthtimes[match.name] = birthtime; + }); + fileStream.on('end', function () { + pathcb(); + }); + }, function (err) { + if (err) { + win.error('External Player Scan:', err); + } else { + win.info('External Player Scan: Completed'); } - } - }); - fileStream.on('end', function () { - pathcb(); - }); - }, function (err) { - - if (err) { - win.error('External Players: scan', err); - return; - } else { - win.info('External Players: scan finished'); - return; + }); } - }); + } - App.Device.ExtPlayer = ExtPlayer; + App.Device.Loaders.ExtPlayer = ExtPlayer; })(window.App); diff --git a/src/app/lib/device/generic.js b/src/app/lib/device/generic.js index 55968e1ecf..967351cd82 100644 --- a/src/app/lib/device/generic.js +++ b/src/app/lib/device/generic.js @@ -2,6 +2,7 @@ 'use strict'; var self; + const fs = require('fs'); // Supports both IPv4 and IPv6 comparison var _sequentialPartsInCommon = function(ip1, ip2) { @@ -24,24 +25,29 @@ }); }; - var Device = Backbone.Model.extend({ - defaults: { - id: 'local', - type: 'local', - typeFamily: 'internal', - name: 'Popcorn Time' - }, - play: function(streamModel) { + class Device extends Backbone.Model { + constructor(attrs) { + super(Object.assign({ + id: 'local', + type: 'local', + typeFamily: 'internal', + name: 'Popcorn Time' + }, attrs)); + } + play(streamModel) { App.vent.trigger('stream:local', streamModel); - }, - getID: function() { + } + getID() { return this.id; } - }); + static scan() { + } + } - var DeviceCollection = Backbone.Collection.extend({ - selected: 'local', - initialize: function() { + class DeviceCollection extends Backbone.Collection { + + selected = 'local'; + initialize() { App.vent.on('device:list', this.list); App.vent.on('device:pause', this.pause); App.vent.on('device:unpause', this.unpause); @@ -53,40 +59,41 @@ App.vent.on('device:seekPercentage', this.seekPercentage); App.vent.on('device:status:update', this.updateStatus); self = this; - }, - list: function() { + } + + list() { _.each(self.models, function(device) { App.vent.trigger('device:add', device); }); - }, - pause: function() { + } + pause() { self.selected.pause(); - }, - unpause: function() { + } + unpause() { self.selected.unpause(); - }, - stop: function() { + } + stop() { self.selected.stop(); - }, - forward: function() { + } + forward() { self.selected.forward(); - }, - backward: function() { + } + backward() { self.selected.backward(); - }, - seek: function(seconds) { + } + seek(seconds) { self.selected.seekBy(seconds); - }, - seekTo: function(newCurrentTime) { + } + seekTo(newCurrentTime) { self.selected.seekTo(newCurrentTime); - }, - seekPercentage: function(percentage) { + } + seekPercentage(percentage) { self.selected.seekPercentage(percentage); - }, - updateStatus: function() { + } + updateStatus() { self.selected.updateStatus(); - }, - startDevice: function(streamModel) { + } + startDevice(streamModel) { if (!this.selected) { this.selected = this.models[0]; } @@ -96,7 +103,6 @@ * best matching IP among all network adapters. Supports IPv4 and IPv6. */ if (this.selected.get('typeFamily') === 'external') { - //console.warn('External Device ', this.selected); var ips = [], ifaces = os.networkInterfaces(); for (var dev in ifaces) { @@ -117,14 +123,14 @@ ); } return this.selected.play(streamModel); - }, + } - setDevice: function(deviceID) { + setDevice(deviceID) { this.selected = this.findWhere({ id: deviceID }); } - }); + } var collection = new DeviceCollection(new Device()); collection.setDevice('local'); @@ -162,8 +168,49 @@ }; App.Device = { - Generic: Device, Collection: collection, + Loaders: { + Device: Device, + }, + rescan: function () { + App.Device.Collection.reset(); + App.Device.Collection.add(new Device()); + for (const i in App.Device.Loaders) { + if (App.Device.Loaders.hasOwnProperty(i)) { + App.Device.Loaders[i].scan(); + } + } + }, + loadDeviceSupport: function() { + var providerPath = './src/app/lib/device/'; + var files = fs.readdirSync(providerPath); + var head = document.getElementsByTagName('head')[0]; + return files + .map(function(file) { + if (!file.match(/\.js$/) || file.match(/generic.js$/) || file.match(/xbmc.js$/)) { + return null; + } + return new Promise((resolve, reject) => { + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = 'lib/device/' + file; + script.onload = function() { + script.onload = null; + win.info('Loaded device provider:', file); + resolve(file); + }; + head.appendChild(script); + }); + }) + .filter(function(q) { + return q; + }); + }, ChooserView: createChooserView }; + + Promise.all(App.Device.loadDeviceSupport()).then(function(data) { + App.Device.rescan(); + }); + })(window.App); diff --git a/src/app/lib/device/xbmc.js b/src/app/lib/device/xbmc.js index a29c606450..0ebf7e93a4 100644 --- a/src/app/lib/device/xbmc.js +++ b/src/app/lib/device/xbmc.js @@ -1,42 +1,43 @@ (function (App) { 'use strict'; - var browser = require('airplay-xbmc').createBrowser(); - var collection = App.Device.Collection; - var makeID = function (baseID) { - return 'airplay-xbmc' + baseID.replace(':', ''); - }; - - var AirplayXBMC = App.Device.Airplay.extend({ - defaults: { - type: 'airplay-xbmc', - typeFamily: 'external' - }, - makeID: makeID, - initialize: function (attrs) { + class AirplayXBMC extends App.Device.Loaders.Airplay { + constructor(attrs) { + super(Object.assign( { + type: 'airplay-xbmc', + typeFamily: 'external' + }, attrs)); + } + static makeID(baseID) { + return 'airplay-xbmc' + baseID.replace(':', ''); + } + initialize(attrs) { this.device = attrs.device; this.attributes.address = this.device.info[0]; } - }); - - browser.on('deviceOn', function (device) { - collection.add(new AirplayXBMC({ - device: device - })); - }); - browser.on('deviceOff', function (device) { - var model = collection.get({ - id: makeID(device.id) - }); - if (model) { - model.destroy(); + static scan() { + var browser = require('airplay-xbmc').createBrowser(); + browser.on('deviceOn', function (device) { + collection.add(new AirplayXBMC({ + device: device + })); + }); + + browser.on('deviceOff', function (device) { + var model = collection.get({ + id: self.makeID(device.id) + }); + if (model) { + model.destroy(); + } + }); + + browser.start(); } - }); - - browser.start(); + } - App.Device.AirplayXBMC = AirplayXBMC; + App.Device.Loaders.AirplayXBMC = AirplayXBMC; })(window.App); diff --git a/src/app/lib/models/content_item.js b/src/app/lib/models/content_item.js index 2aa60950cb..f3158bf9eb 100644 --- a/src/app/lib/models/content_item.js +++ b/src/app/lib/models/content_item.js @@ -16,7 +16,7 @@ providers.metadata && providers.metadata.getImages(attrs) .then(this.set.bind(this)) - .catch(e => console.error('error loading metadata', e)); + .catch(e => win.error('Error loading metadata', e)); this.updateHealth(); this.on('change:torrents', this.updateHealth.bind(this)); @@ -30,7 +30,6 @@ var torrents = this.get('torrents'); if (!torrents) { - console.error('tried to update health, but still no torrents here', this); return false; } diff --git a/src/app/lib/models/favorite_collection.js b/src/app/lib/models/favorite_collection.js index 97c5fd6354..569669c805 100644 --- a/src/app/lib/models/favorite_collection.js +++ b/src/app/lib/models/favorite_collection.js @@ -33,8 +33,9 @@ var torrent = this.providers.torrent; var torrentPromise = torrent.fetch(this.filter); - return Q.all([torrentPromise]) - .spread(function (movies) { + return Promise.all([torrentPromise]) + .then(function (movies) { + movies = movies.flat(); // If a new request was started... _.each(movies, function (movie) { diff --git a/src/app/lib/models/generic_collection.js b/src/app/lib/models/generic_collection.js index 00fee6bd91..95dc5423fb 100644 --- a/src/app/lib/models/generic_collection.js +++ b/src/app/lib/models/generic_collection.js @@ -92,7 +92,7 @@ self.trigger('loaded', self, self.state); }) .catch(function (err) { - console.error('provider error err', err); + win.error('provider error err', err); }); }); }, diff --git a/src/app/lib/models/watchlist_collection.js b/src/app/lib/models/watchlist_collection.js index 561c13c519..f649fda2c6 100644 --- a/src/app/lib/models/watchlist_collection.js +++ b/src/app/lib/models/watchlist_collection.js @@ -21,7 +21,7 @@ }).catch((error) => { this.state = 'error'; this.trigger('loaded', this, this.state); - console.error('WatchlistCollection.fetch()', error); + win.error('WatchlistCollection.fetch()', error); }); }, fetchMore: function () { diff --git a/src/app/lib/plugins/media-name.js b/src/app/lib/plugins/media-name.js deleted file mode 100644 index 15b710af5a..0000000000 --- a/src/app/lib/plugins/media-name.js +++ /dev/null @@ -1,99 +0,0 @@ -((App) => { - const mediaNameSymbol = Symbol('torrentMediaName'); - - // If a value is in the cache for longer than a minute, it is - // assumed to be invalid -- perhaps there was some error in - // initializing the download. We generally expect operations - // to be performed on the order of milliseconds, but we're - // giving a lot of leeway here just for the sake of resilience. - // We may also never consume if the torrent is ready immediately. - const maxTimeInCacheMs = 60 * 1000; - - /** - * When torrents are added, we don't know their title until they tell us they are "ready". - * However, some torrents are never ready, and even if they are ready, it may take - * anywhere from a few seconds for a torrent with good health up to minutes for one with - * poor health. - * This plugin helps provide the name of the source media until we know the actual title - * of the torrent once it is ready. - * To reduce memory usage, all media names are only able to be "consumed" rather than read, - * meaning they can only be read once before they must be re-inserted into this cache. - */ - class MediaNamePlugin { - constructor() { - this._infoHashToMediaName = new Map(); - this._infoHashToInsertTime = new Map(); - // the timeout is arbitrary and can be changed without consequence, but it shouldn't be too short so that - // we avoid iterating over all the entries too often. - this._cleanupTask = setInterval(() => this._clean(), maxTimeInCacheMs); - } - - _remove(infoHash) { - this._infoHashToInsertTime.delete(infoHash); - this._infoHashToMediaName.delete(infoHash); - } - - _clean() { - const now = Date.now(); - for (const [infoHash, insertTime] of this._infoHashToInsertTime) { - if (now - insertTime >= maxTimeInCacheMs) { - this._remove(infoHash); - } - } - } - - /** - * Given an infoHash, gets the cached name of that torrent's - * source media, and deletes it from the cache if it exists. - * @param infoHash - The torrent's infoHash - * @returns {string} - */ - _consumeMediaName(infoHash) { - const mediaName = this._infoHashToMediaName.get(infoHash); - this._remove(infoHash); - return mediaName; - } - - /** - * Sets the original media name to be consumed once downloading begins - * @param infoHash - The torrent to be downloaded - * @param mediaName - The name of the source media for this torrent - */ - setMediaName(infoHash, mediaName) { - this._infoHashToMediaName.set(infoHash, mediaName); - this._infoHashToInsertTime.set(infoHash, Date.now()); - } - - /** - * Get the name of a given torrent. This will use torrent.name if available, - * or the cached media name otherwise. - * @param torrent - * @returns {string} - */ - getMediaName(torrent) { - console.log('getting media name for', torrent); - console.log(this); - if (torrent.name) { - return torrent.name; - } - - if (torrent[mediaNameSymbol]) { - return torrent[mediaNameSymbol]; - } - - const mediaName = this._consumeMediaName(torrent.infoHash); - if (mediaName) { - torrent[mediaNameSymbol] = mediaName; - return mediaName; - } - - return i18n.__('Unknown torrent'); - } - } - - /** - * @namespace {App} - * @type {MediaNamePlugin} - */ - App.plugins.mediaName = new MediaNamePlugin(); -})(window.App); \ No newline at end of file diff --git a/src/app/lib/providers/favorites.js b/src/app/lib/providers/favorites.js index 2f1413a7c0..4dede3a19b 100644 --- a/src/app/lib/providers/favorites.js +++ b/src/app/lib/providers/favorites.js @@ -72,11 +72,10 @@ if (filters.type !== 'All') { matched = []; for (var i in sorted) { - if (sorted[i].imdb_id.indexOf('mal') !== -1) { + if (sorted[i].original_language === 'ja' && sorted[i].genres.includes('animation')) { matched.push(sorted[i]); } } - if (filters.type === 'Anime') { sorted = matched; } else { @@ -191,7 +190,7 @@ page: filters.page, kind: filters.kind }; - if (filters.type === 'Series') { + if (filters.type === 'Series' || filters.type === 'Anime') { params.type = 'show'; } if (filters.type === 'Movies') { @@ -209,9 +208,18 @@ Favorites.prototype.filters = function () { const data = { kinds: ['Favorites', 'Watched'], - types: ['All', 'Movies', 'Series', 'Anime'], + types: ['All'], sorters: ['watched items', 'year', 'title', 'rating'] }; + if (Settings.moviesTabEnable) { + data.types.push('Movies'); + } + if (Settings.seriesTabEnable) { + data.types.push('Series'); + } + if (Settings.animeTabEnable) { + data.types.push('Anime'); + } let filters = { kinds: {}, types: {}, diff --git a/src/app/lib/providers/generic.js b/src/app/lib/providers/generic.js index 0c33d5ec42..7fcf4c78f3 100644 --- a/src/app/lib/providers/generic.js +++ b/src/app/lib/providers/generic.js @@ -38,7 +38,7 @@ function delProvider(name) { if (cache[name]) { - win.info('Delete provider cache', name); + win.info('Delete provider cache:', name); return delete cache[name]; } } @@ -61,7 +61,6 @@ ); } - win.debug('added', name, 'to provider registry'); registry[name] = PO; return name; @@ -105,7 +104,7 @@ } } - win.info('Spawning new provider', name, config); + win.info('Spawning new provider:', name, config); var p = (cache[name] = new provider(config)); //HACK(xaiki): set the provider name in the returned object. diff --git a/src/app/lib/providers/torrent_cache.js b/src/app/lib/providers/torrent_cache.js index b727c27f0b..a06d3dd495 100644 --- a/src/app/lib/providers/torrent_cache.js +++ b/src/app/lib/providers/torrent_cache.js @@ -35,7 +35,6 @@ return Promise.resolve(torrent); }, handleSuccess: function (filePath) { - win.debug('TorrentCache.handleSuccess() ' + filePath + ' stopped: ' + !stateModel); if (!stateModel) { return; } diff --git a/src/app/lib/providers/trakttv.js b/src/app/lib/providers/trakttv.js index 7c6e459418..390817f843 100644 --- a/src/app/lib/providers/trakttv.js +++ b/src/app/lib/providers/trakttv.js @@ -54,7 +54,7 @@ return true; }.bind(this)).catch(function(err) { AdvSettings.set('traktStatus', false); - console.error('Trakt: authentication failed', err); + win.error('Trakt: authentication failed', err); return err; }); }, @@ -66,7 +66,7 @@ AdvSettings.set('traktStatus', auth); this.onReady(); }.bind(this)).catch(function(err) { - console.error('Trakt: auto sign-in failed', err); + win.error('Trakt: auto sign-in failed', err); this.disconnect(); }.bind(this)); } @@ -95,13 +95,12 @@ type: 'movie' }); } else { - console.warn('Cannot sync a movie (' + movie.title + '), no IMDB id provided by Trakt'); + win.error('Cannot sync a movie (' + movie.title + '), no IMDB id provided by Trakt'); } } - console.info('Trakt: marked %s movie(s) as watched', watchedMovies.length); return Database.markMoviesWatched(watchedMovies); }).catch(function(error) { - console.error('Trakt: unable to sync movies', error); + win.error('Trakt: unable to sync movies', error); return watchedMovies; }); }, @@ -128,14 +127,13 @@ } } } else { - console.warn('Cannot sync a show (' + show.show.title + '), no IMDB/TVDB ids provided by Trakt'); + win.error('Cannot sync a show (' + show.show.title + '), no IMDB/TVDB ids provided by Trakt'); } } - console.info('Trakt: marked %s episode(s) as watched', watchedEpisodes.length); return Database.markEpisodesWatched(watchedEpisodes); }).catch(function(error) { - console.error('Trakt: unable to sync shows', error); + win.error('Trakt: unable to sync shows', error); return watchedEpisodes; }); }, @@ -151,7 +149,7 @@ AdvSettings.set('traktLastSync', Date.now()); return true; }).catch(function(error) { - console.error('Trakt: sync failed', error); + win.error('Trakt: sync failed', error); return error; }); }, @@ -207,8 +205,6 @@ data.ids[idType] = id; post[type] = [data]; - console.info('Trakt history - %s %s', call, id); - return this.client.sync.history[call](post); }, @@ -235,7 +231,7 @@ onReady: function(forced, first) { this.authenticated = true; - console.info('Trakt: authenticated'); + win.info('Trakt: authenticated'); var refresh = Settings.traktLastSync + this.cache < Date.now(); var onStart = Settings.traktSyncOnStart; diff --git a/src/app/lib/providers/watchlist.js b/src/app/lib/providers/watchlist.js index 445228f069..0260165efd 100644 --- a/src/app/lib/providers/watchlist.js +++ b/src/app/lib/providers/watchlist.js @@ -96,7 +96,6 @@ return App.Trakt.client.images.get(item).then(function(imgs) { itemList[idx].poster = imgs.poster; itemList[idx].backdrop = imgs.background; - console.log(itemList[idx]); }); }) ); @@ -218,18 +217,15 @@ (filters.force || filters.update) ) { if (filters.update && localStorage.watchlist_update_shows) { - console.log('Watchlist - update one item'); return update(filters.update) .then(resolve) .catch(reject); } else { if (filters.force) { - console.log('Watchlist - force reload'); return load() .then(resolve) .catch(reject); } else { - console.log('Watchlist - this should not be called', filters); reject('SHOULDNT BE CALLED'); } } @@ -239,7 +235,6 @@ !localStorage.watchlist_cached || parseInt(localStorage.watchlist_fetched_time) + 14400000 < Date.now() ) { - console.log('Watchlist - no watchlist cached or cache expired'); if (App.Trakt.authenticated) { return App.Providers.get('Watchlist') .fetch({ force: true }) @@ -249,7 +244,6 @@ reject('Trakt not authenticated'); } } else { - console.log('Watchlist - return cached'); resolve({ results: JSON.parse(localStorage.watchlist_cached), hasMore: false diff --git a/src/app/lib/subtitle/generic.js b/src/app/lib/subtitle/generic.js index 2d0b3e5ec4..47082d66e4 100644 --- a/src/app/lib/subtitle/generic.js +++ b/src/app/lib/subtitle/generic.js @@ -61,7 +61,6 @@ zipEntries = zip.getEntries(); zip.extractAllTo( /*target path*/ fpath, /*overwrite*/ true); fs.unlink(fpath+ext, function (err) {}); - console.debug('Subtitles extracted to : ' + fpath); var found = findSrt(fpath); if (found) { fs.renameSync(found, fpath + '.srt'); @@ -106,7 +105,6 @@ }, download: function (data) { if (data.path && data.url) { - console.debug('Subtitle download url:', data.url); var fileFolder = path.dirname(data.path); try { @@ -118,12 +116,12 @@ downloadFromUrl(data).then(function (spath) { App.vent.trigger('subtitle:downloaded', spath); }).catch(function (error) { - console.error('Subtitle download error:', error); + win.error('Subtitle download error:', error); App.vent.trigger('subtitle:downloaded', null); }); } else { if (Settings.subtitle_language !== 'none') { - console.info('No subtitles downloaded. None picked or language not available'); + win.info('No subtitles downloaded. None picked or language not available'); App.vent.trigger('notification:show', new App.Model.Notification({ title: i18n.__('No subtitles found'), body: i18n.__('Try again later or drop a subtitle in the player'), @@ -157,20 +155,17 @@ var charset = charsetDetect.detect(dataBuff); var detectedEncoding = charset.encoding; - console.debug('SUB charset detected: ', detectedEncoding); // Do we need decoding? if (detectedEncoding.toLowerCase().replace('-', '') === targetEncodingCharset) { callback(dataBuff.toString('utf8')); // We do } else { var langInfo = App.Localization.langcodes[language] || {}; - console.debug('SUB charset expected for \'%s\': ', language, langInfo.encoding); if (langInfo.encoding !== undefined && langInfo.encoding.indexOf(detectedEncoding) < 0) { // The detected encoding was unexepected to the language, so we'll use the most common // encoding for that language instead. detectedEncoding = langInfo.encoding[0]; } - console.debug('SUB charset used: ', detectedEncoding); dataBuff = iconv.encode(iconv.decode(dataBuff, detectedEncoding), targetEncodingCharset); callback(dataBuff.toString('utf8')); } diff --git a/src/app/lib/subtitle/server.js b/src/app/lib/subtitle/server.js index 7032e4cbe0..fea5656ea0 100644 --- a/src/app/lib/subtitle/server.js +++ b/src/app/lib/subtitle/server.js @@ -18,8 +18,6 @@ res.setHeader('Access-Control-Allow-Origin', req.headers.origin); } res.setHeader('Content-Type', 'text/' + ext + ';charset=' + encoding); - win.debug('SubtitlesServer: served vtt/srt with encoding: ' + encoding); - }; if (ext in subtitlePath) { @@ -54,11 +52,9 @@ start: function (data, cb) { encoding = data.encoding || 'utf8'; - win.debug('SubtitleServer: loading', data.srt || data.vtt); if (data.vtt) { fs.readFile(data.vtt, function (err, data) { if (err) { - win.error('SubtitlesServer: Unable to load VTT file'); return; } }); @@ -68,7 +64,6 @@ if (data.srt) { fs.readFile(data.srt, function (err, data) { if (err) { - win.error('SubtitlesServer: Unable to load SRT file'); return; } }); diff --git a/src/app/lib/views/about.js b/src/app/lib/views/about.js index 2b85f6f525..d69d825cb7 100644 --- a/src/app/lib/views/about.js +++ b/src/app/lib/views/about.js @@ -21,7 +21,6 @@ App.vent.trigger('about:close'); }); $('.links,#changelog').tooltip(); - win.info('Show about'); $('#movie-detail').hide(); }, diff --git a/src/app/lib/views/browser/generic_browser.js b/src/app/lib/views/browser/generic_browser.js index a8b92833e9..070444b89f 100644 --- a/src/app/lib/views/browser/generic_browser.js +++ b/src/app/lib/views/browser/generic_browser.js @@ -57,7 +57,6 @@ // })); if (!isNaN(startupTime)) { - win.debug('Butter %s startup time: %sms', Settings.version, (window.performance.now() - startupTime).toFixed(3)); // started in database.js; startupTime = 'none'; if (parseInt(AdvSettings.get('bigPicture'))) { if (AdvSettings.get('bigPicture') !== 100) { diff --git a/src/app/lib/views/disclaimer.js b/src/app/lib/views/disclaimer.js index 5c46a110fa..be9628ebab 100644 --- a/src/app/lib/views/disclaimer.js +++ b/src/app/lib/views/disclaimer.js @@ -22,7 +22,7 @@ AdvSettings.set('updateNotification', document.getElementById('updateNotificationFR').checked ? true : false); AdvSettings.set('disclaimerAccepted', 1); if (document.getElementById('dhtEnableFR').checked) { - App.DhtReader.update(); + App.Updater.updateDHT(); App.vent.trigger('notification:show', new App.Model.Notification({ title: i18n.__('Please wait') + '...', body: i18n.__('Updating the API Server URLs'), @@ -30,7 +30,7 @@ type: 'danger' })); } else { - App.DhtReader.updateOld(); + App.Updater.updateDHTOld(); } App.vent.trigger('disclaimer:close'); }, diff --git a/src/app/lib/views/file_selector.js b/src/app/lib/views/file_selector.js index dad0de8e7f..c10aeecdfd 100644 --- a/src/app/lib/views/file_selector.js +++ b/src/app/lib/views/file_selector.js @@ -3,6 +3,8 @@ var that, magnetName, + importedTorrent, + backdrop, formatMagnet; var FileSelector = Marionette.View.extend({ @@ -12,15 +14,20 @@ events: { 'click .close-icon': 'closeSelector', 'click .file-item *': 'startStreaming', + 'contextmenu .file-item a': 'copytoclip', 'click .store-torrent': 'storeTorrent', 'click .playerchoicemenu li a': 'selectPlayer', - 'click .playerchoicehelp': 'showPlayerList' + 'click .playerchoicehelp': 'showPlayerList', + 'click .playerchoicerefresh': 'refreshPlayerList' }, initialize: function () { that = this; magnetName = Settings.droppedMagnetName; delete(Settings.droppedMagnetName); + importedTorrent = Settings.importedTorrent; + delete(Settings.importedTorrent); + !that.model.get('localFile') ? that.model.set('localFile', false) : null; formatMagnet = function (link) { // format magnet with Display Name @@ -50,14 +57,29 @@ if (!$.trim($('.file-selector-container .file-list').html()).length) { $('.file-selector-container .file-list').html('
  • ' + i18n.__('No results found') + '
  • '); } + backdrop = !importedTorrent && $('.shb-img')[0] && $('.shb-img')[0].style ? $('.shb-img')[0].style.backgroundImage : null; + $('.file-selector-backdrop').css('background-image', backdrop); + this.$('.tooltipped').tooltip({ + html: true, + delay: { + 'show': 800, + 'hide': 100 + } + }); }, startStreaming: function (e) { + $('.tooltipped').tooltip('hide'); + if (that.model.get('localFile')) { + App.vent.trigger('stream:start', that.model, 'local'); + return App.vent.trigger('system:closeFileSelector'); + } var torrent = that.model.get('torrent'); var file = $(e.currentTarget).parent().attr('data-file'); var torrentStart = new Backbone.Model({ torrent: torrent.magnetURI, + backdrop: backdrop ? backdrop.replace('url("', '').replace('")', '') : null, torrent_read: true, file_name: file, device: App.Device.Collection.selected @@ -66,8 +88,10 @@ App.vent.trigger('system:closeFileSelector'); if ($(e.currentTarget).hasClass('item-download')) { if (Settings.showSeedboxOnDlInit) { - App.vent.trigger('torrentCollection:close'); - App.currentview = 'Seedbox'; + if (App.currentview !== 'Torrent-collection') { + App.previousview = App.currentview; + App.currentview = 'Seedbox'; + } App.vent.trigger('seedbox:show'); $('.filter-bar').find('.active').removeClass('active'); $('#filterbar-seedbox').addClass('active'); @@ -78,6 +102,8 @@ } }, + copytoclip: (e) => Common.openOrClipboardLink(e, $(e.target)[0].textContent, i18n.__('filename'), true), + isTorrentStored: function () { var target = App.settings['databaseLocation'] + '/TorrentCollection/'; @@ -117,13 +143,13 @@ if (this.isTorrentStored()) { fs.unlinkSync(target + file); // remove the torrent - win.debug('Torrent Collection: deleted', file); + win.info('Torrent Collection: deleted', file); } else { if (!fs.existsSync(target)) { fs.mkdir(target); // create directory if needed } fs.writeFileSync(target + file, fs.readFileSync(source + file)); // save torrent - win.debug('Torrent Collection: added', file); + win.info('Torrent Collection: added', file); } } else if (Settings.droppedMagnet) { _file = Settings.droppedMagnet, @@ -134,13 +160,13 @@ file = Settings.droppedStoredMagnet; } fs.unlinkSync(target + file); // remove the magnet - win.debug('Torrent Collection: deleted', file); + win.info('Torrent Collection: deleted', file); } else { if (!fs.existsSync(target)) { fs.mkdir(target); // create directory if needed } fs.writeFileSync(target + file, _file); // save magnet link inside readable file - win.debug('Torrent Collection: added', file); + win.info('Torrent Collection: added', file); } } this.isTorrentStored(); // trigger button change @@ -151,19 +177,15 @@ }, selectPlayer: function (e) { - var player = $(e.currentTarget).parent('li').attr('id').replace('player-', ''); - that.model.set('device', player); - if (!player.match(/[0-9]+.[0-9]+.[0-9]+.[0-9]/ig)) { - AdvSettings.set('chosenPlayer', player); - } + Common.selectPlayer(e, that.model); + }, + + showPlayerList: function () { + Common.showPlayerList(); }, - showPlayerList: function(e) { - App.vent.trigger('notification:show', new App.Model.Notification({ - title: '', - body: i18n.__('Popcorn Time currently supports') + '
    ' + extPlayerlst + '.

    ' + i18n.__('There is also support for Chromecast, AirPlay & DLNA devices.'), - type: 'success' - })); + refreshPlayerList: function (e) { + Common.refreshPlayerList(e); }, closeSelector: function (e) { diff --git a/src/app/lib/views/browser/filter_bar.js b/src/app/lib/views/filter_bar.js similarity index 93% rename from src/app/lib/views/browser/filter_bar.js rename to src/app/lib/views/filter_bar.js index 091557ec1a..c192b14a1a 100644 --- a/src/app/lib/views/browser/filter_bar.js +++ b/src/app/lib/views/filter_bar.js @@ -296,6 +296,7 @@ }); } + this.ui.sorterValue.data('value', sorter); this.ui.sorterValue.text($(e.target).text()); this.previousSort = sorter; }, @@ -308,6 +309,7 @@ $(e.target).addClass('active'); var type = $(e.target).attr('data-value'); + this.ui.typeValue.data('value', type); this.ui.typeValue.text($(e.target).text()); this.model.set({ @@ -323,6 +325,7 @@ var genre = $(e.target).attr('data-value'); + this.ui.genreValue.data('value', genre); this.ui.genreValue.text($(e.target).text()); this.model.set({ @@ -337,6 +340,7 @@ $(e.target).addClass('active'); const rating = $(e.target).attr('data-value'); + this.ui.ratingValue.data('value', rating); this.ui.ratingValue.text($(e.target).text()); this.model.set({ @@ -357,36 +361,41 @@ showTorrentCollection: function(e) { e.preventDefault(); if (App.currentview !== 'Torrent-collection') { - if (App.currentview === 'Seedbox') { - App.currentview = App.previousview; - App.vent.trigger('seedbox:close'); + if (App.currentview !== 'Seedbox') { + App.previousview = App.currentview; } - App.previousview = App.currentview; App.currentview = 'Torrent-collection'; App.vent.trigger('about:close'); + App.vent.trigger('seedbox:close'); App.vent.trigger('torrentCollection:show'); this.setActive('Torrent-collection'); } else { - App.currentview = App.previousview; - App.vent.trigger('torrentCollection:close'); + if (!App.ViewStack.includes('seedbox') && !$('#filterbar-seedbox').hasClass('active')) { + App.currentview = App.previousview; + App.vent.trigger('torrentCollection:close'); + } + App.vent.trigger('seedbox:close'); this.setActive(App.currentview); } }, showSeedbox: function(e) { e.preventDefault(); - if (App.currentview !== 'Seedbox') { - if (App.currentview === 'Torrent-collection') { - App.currentview = App.previousview; - App.vent.trigger('torrentCollection:close'); + if (App.currentview !== 'Seedbox' && !App.ViewStack.includes('seedbox')) { + if (App.currentview !== 'Torrent-collection') { + App.previousview = App.currentview; + App.currentview = 'Seedbox'; + } else if (!App.ViewStack.includes('torrent-collection') && !$('#filterbar-torrent-collection').hasClass('active')) { + App.vent.trigger('seedbox:close'); + return this.setActive(App.currentview); } - App.previousview = App.currentview; - App.currentview = 'Seedbox'; App.vent.trigger('about:close'); App.vent.trigger('seedbox:show'); this.setActive('Seedbox'); } else { - App.currentview = App.previousview; + if (App.currentview !== 'Torrent-collection') { + App.currentview = App.previousview; + } App.vent.trigger('seedbox:close'); this.setActive(App.currentview); } diff --git a/src/app/lib/views/help.js b/src/app/lib/views/help.js deleted file mode 100644 index ed60d93176..0000000000 --- a/src/app/lib/views/help.js +++ /dev/null @@ -1,57 +0,0 @@ -(function (App) { - 'use strict'; - var dyks; - - var Help = Marionette.View.extend({ - template: '#help-tpl', - className: 'help', - - events: { - 'click .close-icon': 'closeHelp', - 'click #in-app-reporter': 'reportIssue', - 'click .did-you-know': 'randomizeDyk' - }, - - initialize: function () { - dyks = [ - i18n.__('You can paste magnet links anywhere in %s with CTRL+V.', Settings.projectName), - i18n.__('You can drag & drop a .torrent file into %s.', Settings.projectName), - i18n.__('The %s project was forked from the Popcorn Time project that started in February 2014 and has already had 150 people that contributed more than 3000 times to it\'s development in August 2014.', Settings.projectName), - i18n.__('If a subtitle for a movie or an episode is missing, you can add it on %s.', 'opensubtitles.org'), - i18n.__('If you\'re experiencing connection drop issues, try to reduce the DHT Limit in settings.'), - i18n.__('If you search \"1998\", you can see all the movies or TV series that came out that year.'), - i18n.__('You can login to Trakt.tv to save all your watched items, and synchronize them across multiple devices.'), - i18n.__('Clicking on the rating stars will display a number instead.'), - i18n.__('This application is entirely written in HTML5, CSS3 and Javascript.'), - i18n.__('You can find out more about a movie or a TV series? Just click the IMDb icon.'), - i18n.__('Clicking twice on a \"Sort By\" filter reverses the order of the list.') - ]; - }, - - onAttach: function () { - $('.search input').blur(); - Mousetrap.bind(['esc', 'backspace'], function (e) { - App.vent.trigger('help:close'); - }); - this.randomizeDyk(); - }, - - randomizeDyk: function () { - var dyk = dyks[_.random(dyks.length - 1)]; - $('.randomized-dyk').html(dyk); - }, - - reportIssue: function () { - App.vent.trigger('issue:new'); - }, - - onBeforeDestroy: function () {}, - - closeHelp: function () { - App.vent.trigger('help:close'); - } - - }); - - App.View.Help = Help; -})(window.App); diff --git a/src/app/lib/views/init_modal.js b/src/app/lib/views/init_modal.js index bc84c8a7cd..866499e5bc 100644 --- a/src/app/lib/views/init_modal.js +++ b/src/app/lib/views/init_modal.js @@ -16,7 +16,7 @@ }, initialize: function () { - win.info('Loading DB'); + win.info('Loaded DB'); }, onAttach: function () { diff --git a/src/app/lib/views/browser/item.js b/src/app/lib/views/item.js similarity index 97% rename from src/app/lib/views/browser/item.js rename to src/app/lib/views/item.js index fd006dc5f7..2ce504f773 100644 --- a/src/app/lib/views/browser/item.js +++ b/src/app/lib/views/item.js @@ -20,6 +20,7 @@ covers: '.cover-imgs', defaultCover: '.cover', cover: '.cover', + overlay: '.cover-overlay', bookmarkIcon: '.actions-favorites', watchedIcon: '.actions-watched' }, @@ -139,6 +140,9 @@ if (this.model.get('bookmarked') || itemtype.match('bookmarked')) { this.ui.bookmarkIcon.addClass('selected'); + if (Settings.alwaysShowBookmarks) { + this.ui.overlay.addClass('selected'); + } } if (this.model.get('watched') && !itemtype.match('show')) { @@ -290,7 +294,7 @@ App.vent.trigger(itemtype + ':showDetail', this.model.set(data)); }.bind(this)) .catch(function (err) { - console.error('error showing detail:', err); + win.error('error showing detail:', err); $('.spinner').hide(); $('.notification_alert').text(i18n.__('Error loading data, try again later...')).fadeIn('fast').delay(2500).fadeOut('fast'); }); @@ -358,7 +362,7 @@ }).then(function () { return Database.addBookmark(imdb, itemtype); }).then(function () { - console.log('Bookmark added (' + imdb + ')'); + win.info('Bookmark added (' + imdb + ')'); }.bind(this)); }, @@ -374,7 +378,7 @@ }()); return Database.deleteBookmark(imdb).then(function () { - console.log('Bookmark deleted (' + imdb + ')'); + win.info('Bookmark deleted (' + imdb + ')'); return Database[dbCall](imdb); }); }, @@ -400,6 +404,7 @@ this.model.set('bookmarked', false); this.ui.bookmarkIcon.removeClass('selected'); + this.ui.overlay.removeClass('selected'); this.setCoverStates(); this.setTooltips(); @@ -421,6 +426,7 @@ }.bind(this)).then(function () { var id = window.setTimeout(function() {}, 0); while (id--) { window.clearTimeout(id); } + $('.notification_alert').stop(); App.vent.trigger('notification:close'); App.vent.trigger('notification:show', new App.Model.Notification({ title: '', @@ -444,7 +450,7 @@ this.setTooltips(); } }.bind(this)).catch(function (err) { - console.error('item.addBookmarked failed:', err); + win.error('item.addBookmarked failed:', err); $('.notification_alert').text(i18n.__('Error loading data, try again later...')).fadeIn('fast').delay(2500).fadeOut('fast'); this.ui.bookmarkIcon.removeClass('selected'); }.bind(this)); diff --git a/src/app/lib/views/browser/list.js b/src/app/lib/views/list.js similarity index 100% rename from src/app/lib/views/browser/list.js rename to src/app/lib/views/list.js diff --git a/src/app/lib/views/player/loading.js b/src/app/lib/views/loading.js similarity index 92% rename from src/app/lib/views/player/loading.js rename to src/app/lib/views/loading.js index e677d13a67..6922aa1e83 100644 --- a/src/app/lib/views/player/loading.js +++ b/src/app/lib/views/loading.js @@ -30,12 +30,7 @@ playingbar: '#playingbar-contents', minimizeIcon: '.minimize-icon', maximizeIcon: '.maximize-icon', - userIp: '#userIp', - userCity: '#userCity', - userCountry: '#userCountry', - userZIP: '#userZIP', - userISP: '#userISP', - map: '#map' + magnetIcon: '.magnet-icon' }, events: { @@ -60,7 +55,7 @@ var that = this; App.vent.trigger('settings:close'); App.vent.trigger('about:close'); - $('.button:not(#download-torrent), .show-details .sdo-watch, .sdow-watchnow, .show-details #download-torrent, .file-item, .file-item a, .result-item, .collection-paste, .collection-import, .seedbox .item-play, #torrent-list .item-row, #torrent-show-list .item-row').addClass('disabled'); + $('.button:not(#download-torrent, #cancel-button), .show-details .sdo-watch, .sdow-watchnow, .show-details #download-torrent, .file-item, .file-item a, .result-item, .collection-paste, .collection-import, .seedbox .item-play, #torrent-list .item-row, #torrent-show-list .item-row').addClass('disabled'); $('#watch-now, #watch-trailer, .playerchoice, .file-item, .file-item a, .result-item, .result-item > *:not(.item-icon), .seedbox .item-play, #torrent-list .item-play, #torrent-show-list .item-play').prop('disabled', true); // If a child was removed from above this view App.vent.on('viewstack:pop', function() { @@ -149,6 +144,9 @@ win.info('Loading torrent:', state); this.ui.stateTextDownload.text(i18n.__(state)); if (streamInfo) { + if (streamInfo.get('torrentModel').get('localFile')) { + streamInfo.set({device: streamInfo.get('torrentModel').get('torrentModel').get('device'), src: streamInfo.get('torrentModel').get('src')}); + } if (streamInfo.get('downloaded')) { this.ui.stateTextDownloadedFormatted.text(Common.fileSize(streamInfo.get('downloaded')) + ' / '); } @@ -194,6 +192,11 @@ this.ui.seedStatus.css('visibility', 'visible'); this.ui.progressbar.parent().css('visibility', 'visible'); this.ui.stateTextDownloadedFormatted.show(); + if (streamInfo.get('torrentModel').get('localFile')) { + this.ui.magnetIcon.css('visibility', 'hidden'); + this.ui.progressbar.parent().css('visibility', 'hidden'); + streamInfo.set({downloaded: streamInfo.get('size'), downloadedPercent: 100}); + } if (streamInfo.get('src') && Settings.ipAddress) { this.ui.stateTextStreamUrl.text(streamInfo.get('src').replace('127.0.0.1', Settings.ipAddress)); } @@ -224,7 +227,7 @@ this.ui.downloadSpeed.hide(); this.ui.stateTextRemaining.hide(); $('#rbreak1,#rbreak2,#rbreak3,#rdownl,#ractpr,#maxdl,#maxdllb').hide(); - $('.cancel-button').css('background-color', '#27ae60'); + this.ui.cancel_button.css({'background-color': '#27ae60', 'color': '#fff'}); this.ui.maximizeIcon.addClass('done'); this.ddone = true; } @@ -239,7 +242,7 @@ if (status.media !== undefined && status.media.duration !== undefined) { var playedPercent = (status.currentTime / status.media.duration) * 100; this.ui.playingbar.css('width', playedPercent.toFixed(1) + '%'); - win.debug( + win.info( 'ExternalStream: %s: %ss / %ss (%s%)', status.playerState, status.currentTime.toFixed(1), @@ -257,7 +260,6 @@ // If media encountered error, most likely unsupported codecs with chromecast if (status.idleReason === 'ERROR') { win.error('Device can\'t play the video'); - win.debug('Status: ', status); App.vent.trigger('notification:show', new App.Model.Notification({ title: i18n.__('Device can\'t play the video'), body: i18n.__('Your device might not support the video format/codecs.
    Try other resolution quality or casting with VLC'), @@ -345,18 +347,15 @@ }, forwardStreaming: function() { - win.debug('Forward triggered'); App.vent.trigger('device:forward'); }, backwardStreaming: function() { - win.debug('Backward triggered'); App.vent.trigger('device:backward'); }, seekStreaming: function(e) { var percentClicked = (e.offsetX / e.currentTarget.clientWidth) * 100; - win.debug('Seek (%s%) triggered', percentClicked.toFixed(2)); App.vent.trigger('device:seekPercentage', percentClicked); }, @@ -404,7 +403,7 @@ onBeforeDestroy: function() { $('.filter-bar').show(); $('#header').removeClass('header-shadow'); - $('.button, #watch-now, .show-details .sdo-watch, .sdow-watchnow, .playerchoice, .file-item, .file-item a, .result-item, .result-item > *:not(.item-icon), .trash-torrent, .collection-paste, .collection-import, .seedbox .item-play, .seedbox .exit-when-done, #torrent-list .item-row, #torrent-show-list .item-row, #torrent-list .item-play, #torrent-show-list .item-play').removeClass('disabled').removeProp('disabled'); + $('.button:not(#cancel-button), #watch-now, .show-details .sdo-watch, .sdow-watchnow, .playerchoice, .file-item, .file-item a, .result-item, .result-item > *:not(.item-icon), .trash-torrent, .collection-paste, .collection-import, .seedbox .item-play, .seedbox .exit-when-done, #torrent-list .item-row, #torrent-show-list .item-row, #torrent-list .item-play, #torrent-show-list .item-play').removeClass('disabled').removeProp('disabled'); Mousetrap.bind(['esc', 'backspace'], function(e) { App.vent.trigger('show:closeDetail'); App.vent.trigger('movie:closeDetail'); diff --git a/src/app/lib/views/main_window.js b/src/app/lib/views/main_window.js index ee686b7cf7..96d0eac905 100644 --- a/src/app/lib/views/main_window.js +++ b/src/app/lib/views/main_window.js @@ -19,7 +19,6 @@ Disclaimer: '#disclaimer-container', About: '#about-container', Keyboard: '#keyboard-container', - Help: '#help-container', TorrentCollection: '#torrent-collection-container', Notification: '#notification', Seedbox: '#seedbox-container' @@ -93,11 +92,8 @@ // Help App.vent.on('help:show', _.bind(this.showHelp, this)); - App.vent.on( - 'help:close', - _.bind(this.getRegion('Help').empty, this.getRegion('Help')) - ); - App.vent.on('help:toggle', _.bind(this.toggleHelp, this)); + App.vent.on('help:close',_.bind(this.showHelp, this)); + App.vent.on('help:toggle', _.bind(this.showHelp, this)); // Movies App.vent.on('movie:showDetail', _.bind(this.showMovieDetail, this)); @@ -181,7 +177,6 @@ }, showSubtitles: function(model) { - win.debug('Show subtitles', model); var s = new App.View.Subtitles({ model: model }); @@ -239,7 +234,7 @@ const torrent_cache_dir = path.join(Settings.tmpLocation, 'TorrentCache'); if (!fs.existsSync(torrent_cache_dir)) { fs.mkdir(torrent_cache_dir, function (err) { - if (err && err.errno !== '-4075') { console.log('error creating TorrentCache dir', err); } + if (err && err.errno !== '-4075') { win.error('error creating TorrentCache dir', err); } }); } @@ -260,7 +255,7 @@ const torrent_cache_dir2 = path.join(Settings.downloadsLocation, 'TorrentCache'); if (!fs.existsSync(torrent_cache_dir2)) { fs.mkdir(torrent_cache_dir2, function (err) { - if (err && err.errno !== '-4075') { console.log('error creating Downloads TorrentCache dir', err); } + if (err && err.errno !== '-4075') { win.error('error creating Downloads TorrentCache dir', err); } }); } } @@ -475,15 +470,7 @@ }, showHelp: function(e) { - this.showChildView('Help', new App.View.Help()); - }, - - toggleHelp: function(e) { - if ($('.help-container').length > 0) { - App.vent.trigger('help:close'); - } else { - this.showHelp(); - } + nw.Shell.openExternal(Settings.projectBlog + '/FAQ'); }, preventDefault: function(e) { diff --git a/src/app/lib/views/movie_detail.js b/src/app/lib/views/movie_detail.js index 7f0872bfd9..2144d19523 100644 --- a/src/app/lib/views/movie_detail.js +++ b/src/app/lib/views/movie_detail.js @@ -77,7 +77,6 @@ }, onUpdateTorrentsList: function(lang) { - console.log('Update Torrents List: ', lang); this.getRegion('TorrentList').empty(); if (!lang) { return; @@ -96,7 +95,6 @@ onChangeQuality: function (quality) { this.model.set('quality', quality); this.toggleSourceLink(quality); - win.debug('about to render health button'); healthButton.render(); }, diff --git a/src/app/lib/views/play_control.js b/src/app/lib/views/play_control.js index 0fcb2996da..536bd79d4e 100644 --- a/src/app/lib/views/play_control.js +++ b/src/app/lib/views/play_control.js @@ -17,6 +17,7 @@ 'click .favourites-toggle': 'toggleFavourite', 'click .playerchoicemenu li a': 'selectPlayer', 'click .playerchoicehelp': 'showPlayerList', + 'click .playerchoicerefresh': 'refreshPlayerList', 'click .watched-toggle': 'toggleWatched', 'mousedown #subs-dropdown': 'hideTooltipsSubs', 'click .connect-opensubtitles': 'connectOpensubtitles', @@ -73,8 +74,10 @@ this.model.set('showTorrents', false); this.ui.showTorrents.show(); + $('.playerchoicerefresh, .playerchoicehelp').tooltip({html: true, delay: {'show': 800,'hide': 100}}); + if ($('.loading .maximize-icon').is(':visible') || $('.player .maximize-icon').is(':visible')) { - $('.button:not(#download-torrent)').addClass('disabled'); + $('.button:not(#download-torrent, #cancel-button)').addClass('disabled'); $('#watch-now, #watch-trailer, .playerchoice').prop('disabled', true); } }, @@ -324,23 +327,16 @@ _this.getRegion('qualitySelector').currentView.selectNext(); }, - selectPlayer: function(e) { - var player = $(e.currentTarget) - .parent('li') - .attr('id') - .replace('player-', ''); - this.model.set('device', player); - if (!player.match(/[0-9]+.[0-9]+.[0-9]+.[0-9]/gi)) { - AdvSettings.set('chosenPlayer', player); - } + selectPlayer: function (e) { + Common.selectPlayer(e, this.model); + }, + + showPlayerList: function () { + Common.showPlayerList(); }, - showPlayerList: function(e) { - App.vent.trigger('notification:show', new App.Model.Notification({ - title: '', - body: i18n.__('Popcorn Time currently supports') + '
    ' + extPlayerlst + '.

    ' + i18n.__('There is also support for Chromecast, AirPlay & DLNA devices.'), - type: 'success' - })); + refreshPlayerList: function (e) { + Common.refreshPlayerList(e); }, showAllTorrents: function() { diff --git a/src/app/lib/views/player/player.js b/src/app/lib/views/player.js similarity index 95% rename from src/app/lib/views/player/player.js rename to src/app/lib/views/player.js index 29a1055aec..a36f55d3d2 100644 --- a/src/app/lib/views/player/player.js +++ b/src/app/lib/views/player.js @@ -259,7 +259,6 @@ } if ((this.video.duration() - this.video.currentTime()) < 60) { var playingNext = $('.playing_next'); - win.info('Showing Auto Play message'); this.autoplayisshown = true; playingNext.show(); playingNext.appendTo('div#video_player'); @@ -272,7 +271,6 @@ $('.playing_next #nextCountdown').text(count); } else { if (this.autoplayisshown) { - win.info('Hiding Auto Play message'); $('.playing_next').hide(); $('.playing_next #nextCountdown').text(''); this.autoplayisshown = false; @@ -325,15 +323,13 @@ copytoclip: (e) => Common.openOrClipboardLink(e, e.target.textContent.replace(' - Trailer', ''), i18n.__($(e.target).data('copy')), true), onPlayerReady: function () { - win.debug('Player - data loaded in %sms', (Date.now() - this.playerWasReady)); - // set volume this.player.volume(Settings.playerVolume); // resume position if (Settings.lastWatchedTitle === this.model.get('title') && Settings.lastWatchedTime > 0) { var position = Settings.lastWatchedTime; - win.debug('Resuming position to', position.toFixed(), 'secs'); + win.info('Resuming position to', position.toFixed(), 'secs'); this.player.currentTime(position); } else if (Settings.traktPlayback) { var type = this.isMovie(); @@ -342,7 +338,7 @@ var total = this.video.duration(); var position = (position_percent / 100) * total | 0; if (position > 0) { - win.debug('Resuming position to', position.toFixed(), 'secs (reported by Trakt)'); + win.info('Resuming position to', position.toFixed(), 'secs (reported by Trakt)'); this.player.currentTime(position); } }.bind(this)); @@ -388,12 +384,12 @@ this.wasSeek = true; } else { this.wasSeek = false; - this.ui.play.hide().dequeue().css('transform', 'scale(1)'); - this.ui.pause.appendTo('div#video_player'); - this.ui.pause.show().delay(50).queue(function () { + try { this.ui.play.hide().dequeue().css('transform', 'scale(1)'); } catch (error) {} + try { this.ui.pause.appendTo('div#video_player'); } catch (error) {} + try { this.ui.pause.show().delay(50).queue(function () { this.ui.pause.css('transform', 'scale(1.8)').fadeOut(400).dequeue(); - }.bind(this)); - this.ui.maxPlayCtrlIcon.removeClass('fa-pause').addClass('fa-play'); + }.bind(this)); } catch (error) {} + try { this.ui.maxPlayCtrlIcon.removeClass('fa-pause').addClass('fa-play'); } catch (error) {} App.vent.trigger('player:pause'); this.sendToTrakt('pause'); } @@ -440,7 +436,7 @@ $('#player_drag').show(); var that = this; - $('.button:not(#download-torrent), .show-details .sdo-watch, .sdow-watchnow, .show-details #download-torrent, .file-item, .file-item a, .result-item, .collection-paste, .collection-import, .seedbox .item-play, #torrent-list .item-row, #torrent-show-list .item-row').addClass('disabled'); + $('.button:not(#download-torrent, #cancel-button), .show-details .sdo-watch, .sdow-watchnow, .show-details #download-torrent, .file-item, .file-item a, .result-item, .collection-paste, .collection-import, .seedbox .item-play, #torrent-list .item-row, #torrent-show-list .item-row').addClass('disabled'); $('#watch-now, #watch-trailer, .playerchoice, .file-item, .file-item a, .result-item, .result-item > *:not(.item-icon), .seedbox .item-play, #torrent-list .item-play, #torrent-show-list .item-play').prop('disabled', true); // Double Click to toggle Fullscreen @@ -458,6 +454,10 @@ this.processNext(); } + if (this.model.get('localFile')) { + this.model.set({downloaded: this.model.get('size'), downloadedPercent: 100}); + } + this.$('.tooltipped').tooltip({ html: true, delay: { @@ -540,10 +540,12 @@ // Local subtitle hack App.vent.on('customSubtitles:added', function (subpath) { + var currentTime = 0; + try { currentTime = that.video.currentTime(); } catch (error) {}; that.customSubtitles = { subPath: subpath, added_at: Date.now(), - timestamp: that.video.currentTime(), + timestamp: currentTime, modified: false }; $('#video_player li:contains("' + i18n.__('Disabled') + '")').on('click', function () { @@ -641,7 +643,6 @@ } }, playNextNot: function () { - win.info('Hiding Auto Play message'); $('.playing_next').hide(); $('.playing_next #nextCountdown').text(''); !this.autoplayisshown; @@ -712,7 +713,7 @@ this.sendToTrakt('stop'); // remove wrong metadata - var title = path.basename(this.model.get('src')); + var title = this.model.get('filename') || path.basename(this.model.get('src')); this.model.set('imdb_id', false); this.model.set('cover', false); this.model.set('title', title); @@ -735,7 +736,11 @@ var item; for (var i = $('.vjs-subtitles-button .vjs-menu-item').length - 1; i > 0; i--) { item = $('.vjs-subtitles-button .vjs-menu-item')[i]; - if (item.innerText !== i18n.__('Subtitles') && item.innerText !== i18n.__('Custom...') && item.innerText !== i18n.__('Disabled')) { + if (item.innerText !== i18n.__('Subtitles') && item.innerText !== i18n.__('Custom...') && item.innerText !== i18n.__('Disabled') && item.innerText !== i18n.__('Local')) { + if (item.classList.contains('vjs-selected')) { + this.prevSub = $('.vjs-subtitles-button .vjs-menu-item')[0]; + this.prevSub.click(); + } item.remove(); } } @@ -1177,13 +1182,13 @@ if (curVideo[0]) { var multPer = ((curVideo[0].videoWidth / curVideo[0].videoHeight) / (screen.width / screen.height))*100; if (curVideo.width() > $('#video_player').width() || curVideo.height() > $('#video_player').height()) { - curVideo.css({'width': '100%', 'height': '100%', 'left': '0', 'top': '0'}); + curVideo.removeAttr('style'); this.displayOverlayMsg(i18n.__('Original')); } else if (multPer > 100) { - curVideo.css({'width': multPer + '%', 'left': 50-multPer/2 + '%'}); + curVideo.css({'width': multPer + '%', 'left': 50-multPer/2 + '%', 'border': 'none'}); this.displayOverlayMsg(i18n.__('Fit screen')); } else if (multPer < 100) { - curVideo.css({'height': 10000/multPer + '%', 'top': 50-5000/multPer + '%'}); + curVideo.css({'height': 10000/multPer + '%', 'top': 50-5000/multPer + '%', 'border': 'none'}); this.displayOverlayMsg(i18n.__('Fit screen')); } else { this.displayOverlayMsg(i18n.__('Video already fits screen')); @@ -1268,7 +1273,7 @@ if (this.inFullscreen && !win.isFullscreen) { $('.btn-os.fullscreen').removeClass('active'); } - $('.button, #watch-now, .show-details .sdo-watch, .sdow-watchnow, .playerchoice, .file-item, .file-item a, .result-item, .result-item > *:not(.item-icon), .trash-torrent, .collection-paste, .collection-import, .seedbox .item-play, .seedbox .exit-when-done, #torrent-list .item-row, #torrent-show-list .item-row, #torrent-list .item-play, #torrent-show-list .item-play').removeClass('disabled').removeProp('disabled'); + $('.button:not(#cancel-button), #watch-now, .show-details .sdo-watch, .sdow-watchnow, .playerchoice, .file-item, .file-item a, .result-item, .result-item > *:not(.item-icon), .trash-torrent, .collection-paste, .collection-import, .seedbox .item-play, .seedbox .exit-when-done, #torrent-list .item-row, #torrent-show-list .item-row, #torrent-list .item-play, #torrent-show-list .item-play').removeClass('disabled').removeProp('disabled'); this.unbindKeyboardShortcuts(); Mousetrap.bind('ctrl+v', function (e) { }); diff --git a/src/app/lib/views/quality-selector.js b/src/app/lib/views/quality_selector.js similarity index 100% rename from src/app/lib/views/quality-selector.js rename to src/app/lib/views/quality_selector.js diff --git a/src/app/lib/views/seedbox.js b/src/app/lib/views/seedbox.js index 114cf75de4..410d4865e1 100644 --- a/src/app/lib/views/seedbox.js +++ b/src/app/lib/views/seedbox.js @@ -97,7 +97,7 @@ isTorrentInList: torrent => Boolean(document.getElementById(torrent.infoHash)), addTorrentToList(torrent) { - $('.notorrents-info').hide(); + $('.seedbox .notorrents-info').hide(); let className = 'tab-torrent'; if ($('.tab-torrent.active').length <= 0) { className += ' active'; @@ -106,14 +106,14 @@ `
  • - - + +
    ${App.plugins.mediaName.getMediaName(torrent)}
    - 0 Kb/s + 0 Kb/s 0 Kb/s - +
  • ` ); $('.seedbox-overview').show(); @@ -208,6 +208,7 @@ onRemoveTorrentClicked(e) { try { e.stopPropagation(); } catch(err) {} + $('.tooltipped').tooltip('hide'); const torrent = this.getTorrentFromEvent(e.currentTarget); if (torrent) { if (App.settings.delSeedboxCache === 'always') { @@ -255,8 +256,8 @@ } }); $(`#${torrent.infoHash}`).remove(); - if ($('.tab-torrent').length <= 0) { - $('.notorrents-info').show(); + if ($('.seedbox-torrents .tab-torrent').length <= 0) { + $('.seedbox-torrents .notorrents-info').show(); $('.seedbox-overview').hide(); } } @@ -276,7 +277,7 @@ this.updateView($(e.currentTarget), true /*wasJustSelected*/); }, - copytoclip: (e) => Common.openOrClipboardLink(e, $(e.target)[0].textContent, ($(e.target)[0].className || $(e.target)[0].id ? i18n.__('title') : i18n.__('filename')), true), + copytoclip: (e) => Common.openOrClipboardLink(e, $(e.target)[0].textContent, (($(e.target)[0].className && $(e.target)[0].className !== 'tooltipped') || $(e.target)[0].id ? i18n.__('title') : i18n.__('filename')), true), openItem: function (e) { const hash = $('.tab-torrent.active')[0].getAttribute('id'); @@ -288,6 +289,7 @@ addItem: function (e) { e.stopPropagation(); + $('.tooltipped').tooltip('hide'); const target = $(e.target); const oldScroll = $('.seedbox-infos-synopsis').scrollTop(); const hash = $('.tab-torrent.active')[0].getAttribute('id'); @@ -323,6 +325,7 @@ removeItem: function (e) { e.stopPropagation(); + $('.tooltipped').tooltip('hide'); const hash = $('.tab-torrent.active')[0].getAttribute('id'); const oldScroll = $('.seedbox-infos-synopsis').scrollTop(); const thisTorrent = App.WebTorrent.torrents.find(torrent => torrent.infoHash === hash); @@ -454,7 +457,7 @@ const torrent = App.WebTorrent.get(infoHash); if (wasJustSelected) { this.updateHealth(torrent); - const $fileList = $('.torrents-info > ul.file-list'); + const $fileList = $('.seedbox-infos-synopsis .torrents-info > ul.file-list'); $fileList.empty(); try { torrent.files.sort(function(a, b){ @@ -474,31 +477,28 @@ if (!file.hidden && (file.done || torrent._selections.some(function (el) { return el.from === file._startPiece || el.to === file._endPiece; }))) { selected = true; } - $fileList.append(`
  • - ${file.name} - - - + $fileList.append(`
  • + ${file.name} + + + ${Common.fileSize(file.length)}
  • `); } if (totalfiles < 2) { - $('.file-item a').css('width', 'calc(100% - 22px)'); - $('.file-item .filesize').css('display', 'none'); + $('.seedbox .file-item a').css('width', 'calc(100% - 22px)'); + $('.seedbox .file-item .filesize').css('display', 'none'); } if (active) { $('.seedbox .item-play').addClass('disabled').prop('disabled', true); } - $('.file-item').tooltip({ + $('.seedbox .file-item a, .seedbox .item-play, .seedbox .item-download, .seedbox .item-remove').tooltip({ html: true, delay: { 'show': 800, 'hide': 100 } }); - $('.item-play, .item-download, .item-remove').hover(function(){ - $('.file-item').tooltip('hide'); - }); } totalSize = 0; totalDownloaded = 0; diff --git a/src/app/lib/views/settings_container.js b/src/app/lib/views/settings_container.js index f4b7b5aa16..b9890fbabb 100644 --- a/src/app/lib/views/settings_container.js +++ b/src/app/lib/views/settings_container.js @@ -334,6 +334,7 @@ case 'contentLangOnly': case 'dhtEnable': case 'coversShowRating': + case 'alwaysShowBookmarks': case 'showSeedboxOnDlInit': case 'expandedSearch': case 'nativeWindowFrame': @@ -631,6 +632,7 @@ !value ? scrollPosOffset++ : scrollPosOffset--; } /* falls through */ + case 'alwaysShowBookmarks': case 'watchedCovers': case 'defaultFilters': case 'activateTempf': @@ -727,7 +729,7 @@ updateDht: function(e) { let updateMode = e === 'enable' ? e : (e ? 'manual' : ''); - App.DhtReader.update(updateMode); + App.Updater.updateDHT(updateMode); }, updateApp: function(e) { @@ -911,7 +913,7 @@ resetSettings: function (e) { var btn = $(e.currentTarget); - if (!this.areYouSure(btn, i18n.__('Resetting...'))) { + if (!this.areYouSure(btn, i18n.__('Resetting settings...'))) { return; } @@ -927,11 +929,11 @@ flushAllDatabase: function (e) { var btn = $(e.currentTarget); - if (!this.areYouSure(btn, i18n.__('Flushing...'))) { + if (!this.areYouSure(btn, i18n.__('Resetting...'))) { return; } - this.alertMessageWait(i18n.__('We are flushing your databases')); + this.alertMessageWait(i18n.__('We are resetting all databases and settings')); Database.deleteDatabases() .then(function () { @@ -953,12 +955,10 @@ }, openTmpFolder: function () { - win.debug('Opening: ' + App.settings['tmpLocation']); App.settings.os === 'windows' ? nw.Shell.openExternal(App.settings['tmpLocation']) : nw.Shell.openItem(App.settings['tmpLocation']); }, openDownloadsFolder: function () { - win.debug('Opening: ' + App.settings['downloadsLocation']); App.settings.os === 'windows' ? nw.Shell.openExternal(App.settings['downloadsLocation']) : nw.Shell.openItem(App.settings['downloadsLocation']); }, @@ -986,7 +986,6 @@ }, openDatabaseFolder: function () { - win.debug('Opening: ' + App.settings['databaseLocation']); App.settings.os === 'windows' ? nw.Shell.openExternal(App.settings['databaseLocation']) : nw.Shell.openItem(App.settings['databaseLocation']); }, @@ -1007,9 +1006,7 @@ that.alertMessageSuccess(false, btn, i18n.__('Export Database'), i18n.__('Database Successfully Exported')); }); - } catch (err) { - console.log(err); - } + } catch (err) {} // reset fileinput so it detect change even if we select same folder again fileinput.val(''); }); @@ -1051,9 +1048,7 @@ that.alertMessageSuccess(true); } catch (err) { - console.log(err); that.alertMessageFailed(i18n.__('Invalid Database File Selected')); - win.warn('Failed to Import Database'); } // reset fileinput so it detect change even if we select same folder again fileinput.val(''); diff --git a/src/app/lib/views/show_detail.js b/src/app/lib/views/show_detail.js index f07a0d2613..b7abfa14c3 100644 --- a/src/app/lib/views/show_detail.js +++ b/src/app/lib/views/show_detail.js @@ -37,7 +37,8 @@ 'mousedown .shp-img': 'clickPoster', 'mousedown .show-detail-container': 'exitZoom', 'mousedown .shm-title, .sdoi-title, .episodeData div': 'copytoclip', - 'click .playerchoicehelp': 'showPlayerList' + 'click .playerchoicehelp': 'showPlayerList', + 'click .playerchoicerefresh': 'refreshPlayerList' }, regions: { @@ -160,7 +161,6 @@ }, onUpdateTorrentsList: function(info) { - console.log('Update Torrents List: ', info); if (!info) { this.getRegion('torrentList').empty(); this.getRegion('torrentShowList').empty(); @@ -257,6 +257,8 @@ App.Device.ChooserView('#player-chooser').render(); $('.spinner').hide(); + $('.playerchoicerefresh, .playerchoicehelp').tooltip({html: true, delay: {'show': 800,'hide': 100}}); + if ($('.loading .maximize-icon').is(':visible') || $('.player .maximize-icon').is(':visible')) { $('.sdo-watch, .sdow-watchnow, #download-torrent').addClass('disabled'); $('#watch-now').prop('disabled', true); @@ -972,19 +974,15 @@ }, selectPlayer: function (e) { - var player = $(e.currentTarget).parent('li').attr('id').replace('player-', ''); - _this.model.set('device', player); - if (!player.match(/[0-9]+.[0-9]+.[0-9]+.[0-9]/ig)) { - AdvSettings.set('chosenPlayer', player); - } + Common.selectPlayer(e, _this.model); + }, + + showPlayerList: function () { + Common.showPlayerList(); }, - showPlayerList: function(e) { - App.vent.trigger('notification:show', new App.Model.Notification({ - title: '', - body: i18n.__('Popcorn Time currently supports') + '
    ' + extPlayerlst + '.

    ' + i18n.__('There is also support for Chromecast, AirPlay & DLNA devices.'), - type: 'success' - })); + refreshPlayerList: function (e) { + Common.refreshPlayerList(e); }, showAllTorrents: function() { diff --git a/src/app/lib/views/torrent_collection.js b/src/app/lib/views/torrent_collection.js index 2bed4e1bc5..d4a156e081 100644 --- a/src/app/lib/views/torrent_collection.js +++ b/src/app/lib/views/torrent_collection.js @@ -183,7 +183,7 @@ }); resolve(results); }).catch(function (err) { - console.error('ThePirateBay search:', err); + win.error('ThePirateBay search:', err); resolve(results); }); }); @@ -221,7 +221,7 @@ }); resolve(results); }).catch(function (err) { - console.error('1337x search:', err); + win.error('1337x search:', err); resolve(results); }); }); @@ -259,7 +259,7 @@ }); resolve(results); }).catch(function (err) { - console.error('SolidTorrents search:', err); + win.error('SolidTorrents search:', err); resolve(results); }); }); @@ -297,7 +297,7 @@ }); resolve(results); }).catch(function (err) { - console.error('TorrentGalaxy search:', err); + win.error('TorrentGalaxy search:', err); resolve(results); }); }); @@ -335,7 +335,7 @@ }); resolve(results); }).catch(function (err) { - console.error('Nyaa search:', err); + win.error('Nyaa search:', err); resolve(results); }); }); @@ -370,7 +370,7 @@ ]).then(function (results) { var items = removeDupesAndSort(results); that.curitems = items; - console.log('Search Providers: %d results', items.length); + win.info('Search Providers: %d results', items.length); that.$('.online-search').attr('title', items.length + ' results').tooltip('fixTitle').tooltip('show'); hidetooltps = setTimeout(function() { @@ -408,7 +408,7 @@ '
  • '+ '' + item.title + ''+ '
    '+ - '
    '+item.seeds+' / '+item.peers+'
    '+ + '
    '+item.seeds+' / '+item.peers+'
    '+ '
    '+item.size+'
    '+ '
  • ' ); diff --git a/src/app/lib/views/torrent-list.js b/src/app/lib/views/torrent_list.js similarity index 88% rename from src/app/lib/views/torrent-list.js rename to src/app/lib/views/torrent_list.js index 36aab180ab..8fd7676f31 100644 --- a/src/app/lib/views/torrent-list.js +++ b/src/app/lib/views/torrent_list.js @@ -69,11 +69,18 @@ e.stopPropagation(); const torrent = this.getTorrent(e.target); const download = !$(e.target).hasClass('item-play'); + const backdrop = ($('.backdrop')[0] && $('.backdrop')[0].style ? $('.backdrop')[0].style.backgroundImage : ($('.shb-img')[0] && $('.shb-img')[0].style ? $('.shb-img')[0].style.backgroundImage : null)); Settings.droppedMagnet = torrent.url || null; Settings.droppedMagnetName = torrent.title || null; + if ($('.meta-container .title').text()) { + torrent.title = $('.meta-container .title').text(); + } else if ($('.sh-metadata .shm-title').text()) { + torrent.title = $('.sh-metadata .shm-title').text() + ' - ' + $('.sdoi-number').text() + ' - ' + $('.sdoi-title').text(); + } var torrentStart = new Backbone.Model({ torrent: torrent.url, title: this.model.get('select') && !download ? null : torrent.title, + backdrop: backdrop ? backdrop.replace('url("', '').replace('")', '') : null, defaultSubtitle: $('#subs-dropdown .selected-lang')[0] ? $('#subs-dropdown .selected-lang')[0].classList[$('#subs-dropdown .selected-lang')[0].classList.length - 1] : Settings.subtitle_language, imdb_id: $('.list .items .item.selected')[0] ? $('.list .items .item.selected')[0].dataset.imdbId : null, season: $('.tab-episode.active')[0] ? $('.tab-episode.active')[0].attributes['data-season'].value : null, diff --git a/src/app/media_name.js b/src/app/media_name.js new file mode 100644 index 0000000000..ec8865ce17 --- /dev/null +++ b/src/app/media_name.js @@ -0,0 +1,45 @@ +((App) => { + const mediaNameSymbol = Symbol('torrentMediaName'); + const maxTimeInCacheMs = 60 * 1000; + + class MediaNamePlugin { + constructor() { + this._infoHashToMediaName = new Map(); + this._infoHashToInsertTime = new Map(); + this._cleanupTask = setInterval(() => this.cleanMediaNames(), maxTimeInCacheMs); + } + + cleanMediaNames() { + const now = Date.now(); + for (const [infoHash, insertTime] of this._infoHashToInsertTime) { + if (now - insertTime >= maxTimeInCacheMs) { + this._infoHashToInsertTime.delete(infoHash); + this._infoHashToMediaName.delete(infoHash); + } + } + } + + setMediaName(infoHash, mediaName) { + this._infoHashToMediaName.set(infoHash, mediaName); + this._infoHashToInsertTime.set(infoHash, Date.now()); + } + + getMediaName(torrent) { + if (torrent.name) { + return torrent.name; + } + if (torrent[mediaNameSymbol]) { + return torrent[mediaNameSymbol]; + } + const mediaName = this._infoHashToMediaName.get(torrent.infoHash); + this._infoHashToInsertTime.delete(torrent.infoHash); + this._infoHashToMediaName.delete(torrent.infoHash); + if (mediaName) { + torrent[mediaNameSymbol] = mediaName; + return mediaName; + } + return i18n.__('Unknown torrent'); + } + } + App.plugins.mediaName = new MediaNamePlugin(); +})(window.App); diff --git a/src/app/settings.js b/src/app/settings.js index 16bc415847..c01c1f06a2 100644 --- a/src/app/settings.js +++ b/src/app/settings.js @@ -2,10 +2,8 @@ var Settings = { projectName: 'Popcorn Time', projectUrl: '', - projectCi: 'https://github.com/popcorn-official/popcorn-desktop/actions', projectBlog: 'https://github.com/popcorn-official/popcorn-desktop/wiki', projectForum: 'https://www.reddit.com/r/PopcornTimeApp', - projectForum2: '', statusUrl: 'https://status.popcorntime.app', changelogUrl: 'https://github.com/popcorn-official/popcorn-desktop/commits/master', issuesUrl: 'https://github.com/popcorn-official/popcorn-desktop/issues', @@ -79,6 +77,7 @@ Settings.trackers = { 'udp://p4p.arenabg.com:1337', 'udp://exodus.desync.com:6969', 'udp://tracker.torrent.eu.org:451', + 'udp://tracker-udp.gbitt.info:80', 'udp://open.stealth.si:80', 'udp://tracker.dler.org:6969', 'udp://explodie.org:6969', @@ -98,6 +97,7 @@ Settings.animeTabEnable = true; Settings.favoritesTabEnable = true; Settings.watchedTabEnable = true; Settings.coversShowRating = true; +Settings.alwaysShowBookmarks = false; Settings.showSeedboxOnDlInit = true; Settings.expandedSearch = false; Settings.defaultFilters = 'default'; @@ -306,7 +306,7 @@ var AdvSettings = { break; } - return Q(); + return Promise.resolve(true); }, performUpgrade: function() { diff --git a/src/app/lib/streamer.js b/src/app/streamer.js similarity index 88% rename from src/app/lib/streamer.js rename to src/app/streamer.js index 50fbbae3ed..a001ffff86 100644 --- a/src/app/lib/streamer.js +++ b/src/app/streamer.js @@ -1,3 +1,5 @@ +const Server = require("webtorrent/lib/server"); +const FileServer = require("./fileserver"); (function (App) { 'use strict'; var subtitle_retry; @@ -25,6 +27,8 @@ this.downloadOnly = false; // Boolean to indicate preload episode state this.preload = false; + // Boolean to indicate is local file + this.isLocalFile = false; }; WebTorrentStreamer.prototype = { @@ -109,10 +113,50 @@ if (App.WebTorrent.destroyed) { this.stop(); } - this.setModels(model, state); const location = this.downloadOnly && App.settings.separateDownloadsDir ? App.settings.downloadsLocation : App.settings.tmpLocation; - + if (this.isLocalFile) { + if (this.torrentModel.get('isReady')) { + this.handleStreamInfo(); + this.stateModel.set('device', this.torrentModel.get('device')); + this.stateModel.set('title', this.torrentModel.get('title')); + this.stateModel.set('state', this.torrentModel.get('device') === 'local' ? 'ready' : 'playingExternally'); + return App.vent.trigger('stream:ready', this.torrentModel); + } + const index = this.torrentModel.get('video_file').index; + const path = this.torrentModel.get('torrent').get('videoFile'); + const fileForServer = { + name: path.split('/').pop(), + path: path, + length: fs.statSync(path).size, + index: index + }; + this.torrent = this.torrentModel.get('torrent'); + this.torrent.files = []; + this.streamInfo.set('torrentModel', this.torrentModel).updateInfos(); + this.streamInfo.set({ + torrent: this.torrentModel.get('torrent'), + files: this.torrentModel.get('files'), + video_file: this.torrentModel.get('video_file'), + imdb_id: this.torrent.get('imdb_id'), + tvdb_id: this.torrent.get('tvdb_id'), + subtitle: this.torrent.get('subtitle'), + defaultSubtitle: this.torrent.get('defaultSubtitle'), + poster: this.torrent.get('poster'), + backdrop: this.torrent.get('backdrop'), + year: this.torrent.get('year'), + season: this.torrent.get('season'), + episode: this.torrent.get('episode'), + episode_id: this.torrent.get('episode_id'), + quality: this.torrent.get('quality'), + downloadedPercent: 100, + metadataCheckRequired: true, + localFile: true, + isReady: true + }); + this.torrent = null; + return this.createFileServer(fileForServer).then(() => { App.vent.trigger('system:openFileSelector', this.streamInfo); }); + } if (!this.downloadOnly && !this.preload) { this.fetchTorrent(this.torrentModel.get('torrent'), location, model.get('title')).then(function (torrent) { this.torrentModel.set('torrent', this.torrent = torrent); @@ -383,8 +427,8 @@ tmdb: metadatas.type === 'movie' ? metadatas.movie.ids.tmdb : false }).then(function (img) { if (this.torrentModel) { - this.torrentModel.set('backdrop', img.background); - this.torrentModel.set('poster', img.poster); + !this.torrentModel.get('backdrop') ? this.torrentModel.set('backdrop', img.background) : null; + !this.torrentModel.get('poster') ? this.torrentModel.set('poster', img.poster) : null; } }.bind(this)); }, @@ -535,6 +579,35 @@ }.bind(this)); }, + createFileServer: function (file, port) { + return new Promise(function (resolve) { + var serverPort = parseInt((port || Settings.streamPort), 10); + + + if (!serverPort) { + serverPort = this.generatePortNumber(); + } + + try { + const server = new FileServer(file, serverPort); + server.listen(serverPort); + + this.torrentModel.get('torrent').set('server', server); + + var url = 'http://127.0.0.1:' + serverPort + '/' + file.index; + + this.streamInfo.set('src', url); + this.streamInfo.set('type', 'video/mp4'); + + resolve(url); + } catch (e) { + setTimeout(function () { + return this.createFileServer(file, 0).then(resolve); + }.bind(this), 100); + } + }.bind(this)); + }, + handleStreamInfo: function () { this.streamInfo.set('torrentModel', this.torrentModel); this.updateStatsInterval = setInterval(this.streamInfo.updateStats.bind(this.streamInfo), 1000); @@ -571,6 +644,7 @@ setModels: function (model, state) { this.stopped = false; + this.isLocalFile = state === 'local' ? true : false; this.downloadOnly = state === 'downloadOnly' ? true : false; this.preload = state === 'preload' ? true : false; this.torrentModel = model; @@ -635,20 +709,19 @@ } }, - saveCoverToFile: function (location) { + saveCoverToFile: async function (location) { if (this.torrentModel && this.torrentModel.get('type') === 'movie' && this.torrentModel.get('cover') && this.torrentModel.get('torrent').name) { - const request = require('request'); let url = this.torrentModel.get('cover'); - request({ url, encoding: null }, (err, resp, buffer) => { - if (err || buffer.length < 1000) { - return; - } - try { - fs.writeFileSync(path.join(location, this.torrentModel.get('torrent').name) + '/cover.jpg', buffer); - } catch (err) { - fs.writeFileSync(location + '/' + this.torrentModel.get('torrent').name + '_cover.jpg', buffer); - } - }); + const res = await fetch(url); + const buffer = await res.arrayBuffer(); + if (buffer.byteLength < 1000) { + return; + } + try { + fs.writeFileSync(path.join(location, this.torrentModel.get('torrent').name) + '/cover.jpg', Buffer.from(buffer)); + } catch (err) { + fs.writeFileSync(location + '/' + this.torrentModel.get('torrent').name + '_cover.jpg', Buffer.from(buffer)); + } } }, @@ -761,7 +834,7 @@ if (subtitle_retry === undefined) { subtitle_retry=0; } subtitle_retry++; if (subtitle_retry<5) { - console.log('subtitle fetching error. retry: ' + subtitle_retry + ' of 4'); + win.info('subtitle fetching error. retry: ' + subtitle_retry + ' of 4'); this.subtitleReady = false; this.handleSubtitles(subtitle_retry); } else { diff --git a/src/app/styl/Dutchys_-_Dark_Orange_theme.styl b/src/app/styl/Dutchys_-_Dark_Orange_theme.styl index a21aad4f6e..188d60b178 100644 --- a/src/app/styl/Dutchys_-_Dark_Orange_theme.styl +++ b/src/app/styl/Dutchys_-_Dark_Orange_theme.styl @@ -17,19 +17,15 @@ //Main app $BgColor1 = Black $BgColor2 = lighten(Black,5%) - $Text1 = #fff $Text2 = #C9C9C9 $Text3 = #939597 $Text4 = #fff $TextError = #797979 - $CloseButton = #fff $CloseButtonHover = YellowL - $SpinnerColor1 = YellowD2 $SpinnerColor2 = YellowD - $ScrollBarBg = #30333c $ScrollBarThumb = YellowD2 $ScrollBarThumbHover = YellowD @@ -40,39 +36,31 @@ $TbarIconFilter = none $FullScreenButton = #999 $FullScreenButtonHover = YellowL - $FilterBarBg = Black $FilterBarText = #e9e9e9 $FilterBarTextHover = #fff $FilterBarActive = YellowL - $SearchBoxBg = #191818 - $DropDownBg = rgba(Black,0.9) $DropDownBgHover = rgba(YellowL,0.15) $DropDownTextHover = #fff $DropDownText = #d9d9d9 $DropDownOpacity = 0.97 - $FilterBarIcon = $Text1 $FilterBarIconHover = YellowD $FilterBarIcon-PosterWidth = #bababa - - $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9); + $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9) //Buttons $ButtonBg = YellowL $ButtonBgHover = YellowM $ButtonBgActive = YellowD - $ButtonBgDisabled = #737577 - $ButtonBgOk = #27AE60 $ButtonBgWarning = #F15153 - $ButtonText = #000 $ButtonTextHover = #000 - + $ButtonImgInvert = 1 $ButtonRadius = 3px //Checkbox @@ -89,26 +77,20 @@ //TV Series $ShowBgColor1 = $BgColor1 $ShowBgColor2 = $BgColor2 - $EpisodeDetailsBg = $BgColor1 - $ShowText1 = $Text1 $ShowText2 = $Text2 $ShowOddHighlight = lighten($ShowBgColor1,50%) $ShowOddHighlightOp = 0.05 - $SaisonListText = $Text1 $EpisodeListText = $Text2 - $EpisodeSelectorBg = darken(YellowD2,2%) $EpisodeSelectorHover = #26272d $EpisodeSelectorHoverTran = lighten($EpisodeSelectorHover,43%) $EpisodeSelectorText = $ButtonText - $ShowWatchedIcon_false = rgba(#fff,0.2) $ShowWatchedIcon_hover = rgba(#fff,0.4) $ShowWatchedIcon_true = #fff - $QualitySelectorBg = $ButtonBg $QualitySelectorText = $ButtonText @@ -120,13 +102,10 @@ //Settings $SettingsCategoriesText = YellowD $SettingsSeparator = #333 - $InputBoxBg = #232324 $InputBoxText = $Text2 - $SettingsText1 = $Text2 $SettingsText2 = $Text3 - $SettingsButtonText = $ButtonText $SettingsButtonTextHover = $ButtonText @@ -138,10 +117,8 @@ $NotificationOrange = #f07f53 $NotificationError = #f15153 $NotificationBorderColor = #000 - $NotificationBtn = #000 $NotificationBtnText = #fff - $NotifAlertBg = #000 $NotifAlertText = #fff @@ -154,7 +131,6 @@ //Player $PlayerColor = YellowL - // THEME: DUTCHYS DARK ORANGE - END @import 'views/app' diff --git a/src/app/styl/Official_-_Black_&_Yellow_theme.styl b/src/app/styl/Official_-_Black_&_Yellow_theme.styl index 5f5cce7eb7..6333aa205a 100644 --- a/src/app/styl/Official_-_Black_&_Yellow_theme.styl +++ b/src/app/styl/Official_-_Black_&_Yellow_theme.styl @@ -17,19 +17,15 @@ //Main app $BgColor1 = Black $BgColor2 = lighten(Black,5%) - $Text1 = #fff $Text2 = #C9C9C9 $Text3 = #939597 $Text4 = #fff $TextError = #797979 - $CloseButton = #fff $CloseButtonHover = YellowL - $SpinnerColor1 = YellowD2 $SpinnerColor2 = YellowD - $ScrollBarBg = #30333c $ScrollBarThumb = YellowD2 $ScrollBarThumbHover = YellowD @@ -40,39 +36,31 @@ $TbarIconFilter = none $FullScreenButton = #999 $FullScreenButtonHover = YellowL - $FilterBarBg = Black $FilterBarText = #e9e9e9 $FilterBarTextHover = #fff $FilterBarActive = YellowL - $SearchBoxBg = #191818 - $DropDownBg = rgba(Black,0.9) $DropDownBgHover = rgba(YellowL,0.15) $DropDownTextHover = #fff $DropDownText = #d9d9d9 $DropDownOpacity = 0.97 - $FilterBarIcon = $Text1 $FilterBarIconHover = YellowD $FilterBarIcon-PosterWidth = #bababa - - $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9); + $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9) //Buttons $ButtonBg = YellowL $ButtonBgHover = YellowM $ButtonBgActive = YellowD - $ButtonBgDisabled = #737577 - $ButtonBgOk = #27AE60 $ButtonBgWarning = #F15153 - $ButtonText = #000 $ButtonTextHover = #000 - + $ButtonImgInvert = 1 $ButtonRadius = 3px //Checkbox @@ -89,26 +77,20 @@ //TV Series $ShowBgColor1 = $BgColor1 $ShowBgColor2 = $BgColor2 - $EpisodeDetailsBg = $BgColor1 - $ShowText1 = $Text1 $ShowText2 = $Text2 $ShowOddHighlight = lighten($ShowBgColor1,50%) $ShowOddHighlightOp = 0.05 - $SaisonListText = $Text1 $EpisodeListText = $Text2 - $EpisodeSelectorBg = darken(YellowD2,2%) $EpisodeSelectorHover = #26272d $EpisodeSelectorHoverTran = lighten($EpisodeSelectorHover,43%) $EpisodeSelectorText = $ButtonText - $ShowWatchedIcon_false = rgba(#fff,0.2) $ShowWatchedIcon_hover = rgba(#fff,0.4) $ShowWatchedIcon_true = #fff - $QualitySelectorBg = $ButtonBg $QualitySelectorText = $ButtonText @@ -120,13 +102,10 @@ //Settings $SettingsCategoriesText = YellowD $SettingsSeparator = #333 - $InputBoxBg = #232324 $InputBoxText = $Text2 - $SettingsText1 = $Text2 $SettingsText2 = $Text3 - $SettingsButtonText = $ButtonText $SettingsButtonTextHover = $ButtonText @@ -138,10 +117,8 @@ $NotificationOrange = #f07f53 $NotificationError = #f15153 $NotificationBorderColor = #000 - $NotificationBtn = #000 $NotificationBtnText = #fff - $NotifAlertBg = #000 $NotifAlertText = #fff @@ -154,7 +131,6 @@ //Player $PlayerColor = YellowL - // OFFICIAL POPCORN-THEME: BLACK AND YELLOW - END @import 'views/app' diff --git a/src/app/styl/Official_-_Dark_theme.styl b/src/app/styl/Official_-_Dark_theme.styl index cd6c274de8..83db3b5050 100644 --- a/src/app/styl/Official_-_Dark_theme.styl +++ b/src/app/styl/Official_-_Dark_theme.styl @@ -10,19 +10,15 @@ //Main app $BgColor1 = #17181b $BgColor2 = #212225 - $Text1 = #fff $Text2 = #c3c5c7 $Text3 = #a3a5a7 $Text4 = #5b5b5b $TextError = #727272 - $CloseButton = #cccccc $CloseButtonHover = #fff - $SpinnerColor1 = #2187e7 $SpinnerColor2 = rgba(0,183,229,0.9) - $ScrollBarBg = #30333c $ScrollBarThumb = #83888c $ScrollBarThumbHover = #93989c @@ -33,39 +29,31 @@ $TbarIconFilter = none $FullScreenButton = #999 $FullScreenButtonHover = #b2b2b2 - $FilterBarBg = #17181b $FilterBarText = #c3c5c7 $FilterBarTextHover = #fff $FilterBarActive = #2d72d9 - $SearchBoxBg = #0d0d0e - $DropDownBg = #17181b $DropDownBgHover = #0b131f $DropDownTextHover = #fff $DropDownText = #c3c5c7 $DropDownOpacity = 1.00 - $FilterBarIcon = #909498 $FilterBarIconHover = #2468cc $FilterBarIcon-PosterWidth = #6a6e72 - - $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9); + $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9) //$ButtonBg $ButtonBg = #1f375f $ButtonBgHover = #225694 $ButtonBgActive = #2468cc - $ButtonBgDisabled = #393b3d - $ButtonBgOk = #27AE60 $ButtonBgWarning = #F15153 - $ButtonText = #fff $ButtonTextHover = #fff - + $ButtonImgInvert = 0 $ButtonRadius = 3px //Checkbox @@ -82,26 +70,20 @@ //TV Series $ShowBgColor1 = #17181b $ShowBgColor2 = #1f2025 - $EpisodeDetailsBg = #1f2025 - $ShowText1 = #fff $ShowText2 = #8d9296 $ShowOddHighlight = lighten($ShowBgColor1,58%) $ShowOddHighlightOp = 0.05 - $SaisonListText = #fff $EpisodeListText = #8d9296 - $EpisodeSelectorBg = #1b2d4c $EpisodeSelectorHover = #26272d $EpisodeSelectorHoverTran = lighten($EpisodeSelectorHover,43%) $EpisodeSelectorText = #fff - $ShowWatchedIcon_false = rgba(#fff,0.2) $ShowWatchedIcon_hover = rgba(#fff,0.4) $ShowWatchedIcon_true = #fff - $QualitySelectorBg = rgba(43, 110, 210, 0.84) $QualitySelectorText = $ButtonText @@ -113,13 +95,10 @@ //Settings $SettingsCategoriesText = #2d75df $SettingsSeparator = #3a3b3e - $InputBoxBg = #393b3d $InputBoxText = #c3c5c7 - $SettingsText1 = #c3c5c7 $SettingsText2 = #8a8b8e - $SettingsButtonText = #e3e5e7 $SettingsButtonTextHover = #e3e5e7 @@ -131,10 +110,8 @@ $NotificationOrange = #f07f53 $NotificationError = #f15153 $NotificationBorderColor = #000 - $NotificationBtn = #000 $NotificationBtnText = #fff - $NotifAlertBg = #000 $NotifAlertText = #fff @@ -147,7 +124,6 @@ //Player $PlayerColor = #2d75df - // OFFICIAL POPCORN-THEME: DARK - END @import 'views/app' diff --git a/src/app/styl/Official_-_FlaX_theme.styl b/src/app/styl/Official_-_FlaX_theme.styl index bb05b7c9df..8044da2739 100644 --- a/src/app/styl/Official_-_FlaX_theme.styl +++ b/src/app/styl/Official_-_FlaX_theme.styl @@ -9,7 +9,6 @@ White = #f5f7fa Rose = #de5362 - //Fonts $Font = 'Open Sans' $MainFont = 'Open Sans Semibold' @@ -20,19 +19,15 @@ //Main app $BgColor1 = DarkGreen $BgColor2 = Green - $Text1 = White $Text2 = LightGrey $Text3 = LightGrey $Text4 = darken(LightGrey,5) $TextError = Green - $CloseButton = Rose $CloseButtonHover = darken(Rose,5) - $SpinnerColor1 = rgba(#fff,.2) $SpinnerColor2 = Rose - $ScrollBarBg = Green $ScrollBarThumb = LightGreen $ScrollBarThumbHover = Rose @@ -43,39 +38,31 @@ $TbarIconFilter = none $FullScreenButton = #fff $FullScreenButtonHover = Rose - $FilterBarBg = Green $FilterBarText = #fff $FilterBarTextHover = Rose $FilterBarActive = Rose - $SearchBoxBg = rgba(#000,.2) - $DropDownBg = Green $DropDownBgHover = LightGrey $DropDownTextHover = White $DropDownText = lighten(LightGrey,10) $DropDownOpacity = 1.00 - $FilterBarIcon = lighten(LightGrey,10) $FilterBarIconHover = Rose $FilterBarIcon-PosterWidth = Rose - $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, 0) //Buttons $ButtonBg = Rose $ButtonBgHover = darken(Rose,4) $ButtonBgActive = darken(Rose,6) - $ButtonBgDisabled = #9ca5ab - $ButtonBgOk = #27AE60 $ButtonBgWarning = #cf283a - $ButtonText = #fff $ButtonTextHover = #fff - + $ButtonImgInvert = 0 $ButtonRadius = 3px //Checkbox @@ -94,24 +81,18 @@ $ShowBgColor2 = lighten(DarkGreen,7) $ShowOddHighlight = lighten($ShowBgColor1,58%) $ShowOddHighlightOp = 0.05 - $EpisodeDetailsBg = lighten(DarkGreen,3) - $ShowText1 = White $ShowText2 = LightGrey - $SaisonListText = White $EpisodeListText = White - $EpisodeSelectorBg = Rose $EpisodeSelectorHover = lighten($ShowBgColor2,6%) $EpisodeSelectorHoverTran = lighten($EpisodeSelectorHover,43%) $EpisodeSelectorText = #fff - $ShowWatchedIcon_false = rgba(White,0.3) $ShowWatchedIcon_hover = rgba(White,0.6) $ShowWatchedIcon_true = White - $QualitySelectorBg = #df5362 $QualitySelectorText = $ButtonText @@ -123,13 +104,10 @@ //Settings $SettingsCategoriesText = White $SettingsSeparator = rgba(#fff,.1) - $InputBoxBg = darken(Green,4) $InputBoxText = White - $SettingsText1 = darken(White,5) $SettingsText2 = rgba(darken(White,5),.7) - $SettingsButtonText = #fff $SettingsButtonTextHover = #fff @@ -141,10 +119,8 @@ $NotificationOrange = #f07f53 $NotificationError = #cf283a $NotificationBorderColor = White - $NotificationBtn = #fff $NotificationBtnText = #000 - $NotifAlertBg = #191d22 $NotifAlertText = #fff @@ -157,7 +133,6 @@ //Player $PlayerColor = Rose - // OFFICIAL POPCORN-THEME: FLAX - END @import 'views/app' diff --git a/src/app/styl/Official_-_Flat_UI_theme.styl b/src/app/styl/Official_-_Flat_UI_theme.styl index 4e79222614..06d387331b 100644 --- a/src/app/styl/Official_-_Flat_UI_theme.styl +++ b/src/app/styl/Official_-_Flat_UI_theme.styl @@ -10,19 +10,15 @@ //Main app $BgColor1 = #fff $BgColor2 = #eff0f2 - $Text1 = #34495e $Text2 = #d9d9d9 $Text3 = rgba(#34495e,.8) $Text4 = rgba(#34495e,.8) $TextError = rgba(#2c3e50,.8) - $CloseButton = #e74c3c $CloseButtonHover = #c0392b - $SpinnerColor1 = rgba(#fff,.3) $SpinnerColor2 = #1ABC9C - $ScrollBarBg = #ebedef $ScrollBarThumb = #1abc9c $ScrollBarThumbHover = #16a085 @@ -33,39 +29,31 @@ $TbarIconFilter = none $FullScreenButton = #fff $FullScreenButtonHover = #1abc9c - $FilterBarBg = #34495e $FilterBarText = #fff $FilterBarTextHover = #16a085 $FilterBarActive = #16a085 - $SearchBoxBg = #495c6e - $DropDownBg = #34495e $DropDownBgHover = #1ABC9C $DropDownTextHover = #fff $DropDownText = #e1e4e7 $DropDownOpacity = 1.00 - $FilterBarIcon = #fff $FilterBarIconHover = #1ABC9C $FilterBarIcon-PosterWidth = #bababa - $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, 0) //Buttons $ButtonBg = #1ABC9C $ButtonBgHover = #48c9b0 $ButtonBgActive = #16a085 - $ButtonBgDisabled = #d1d5d8 - $ButtonBgOk = #27AE60 $ButtonBgWarning = #F15153 - $ButtonText = #fff $ButtonTextHover = #fff - + $ButtonImgInvert = 0 $ButtonRadius = 6px //Checkbox @@ -82,26 +70,20 @@ //TV Series $ShowBgColor1 = #fff $ShowBgColor2 = #eff0f2 - $EpisodeDetailsBg = #fff - $ShowText1 = #34495e $ShowText2 = #7f8c8d $ShowOddHighlight = lighten($ShowBgColor1,50%) $ShowOddHighlightOp = 0.1 - $SaisonListText = #34495e $EpisodeListText = #34495e - $EpisodeSelectorBg = rgba(#003366,0.6) $EpisodeSelectorHover = darken($ShowBgColor2,10%) $EpisodeSelectorHoverTran = darken($EpisodeSelectorHover,43%) $EpisodeSelectorText = #fff - $ShowWatchedIcon_false = rgba(#34495e,0.3) $ShowWatchedIcon_hover = rgba(#34495e,0.6) $ShowWatchedIcon_true = #34495e - $QualitySelectorBg = $ButtonBg $QualitySelectorText = $ButtonText @@ -113,13 +95,10 @@ //Settings $SettingsCategoriesText = #16a085 $SettingsSeparator = #2c3e50 - $InputBoxBg = #34495e $InputBoxText = #e1e4e7 - $SettingsText1 = #34495e $SettingsText2 = #999 - $SettingsButtonText = #fff $SettingsButtonTextHover = #fff @@ -131,10 +110,8 @@ $NotificationOrange = #f07f53 $NotificationError = #f15153 $NotificationBorderColor = #000 - $NotificationBtn = #000 $NotificationBtnText = #fff - $NotifAlertBg = #000 $NotifAlertText = #fff @@ -147,7 +124,6 @@ //Player $PlayerColor = #16a085 - // OFFICIAL POPCORN-THEME: FLAT - END @import 'views/app' diff --git a/src/app/styl/Official_-_Light_theme.styl b/src/app/styl/Official_-_Light_theme.styl index 232613a4ae..4700fa9596 100644 --- a/src/app/styl/Official_-_Light_theme.styl +++ b/src/app/styl/Official_-_Light_theme.styl @@ -17,19 +17,15 @@ //Main app $BgColor1 = White $BgColor2 = Grey - $Text1 = Black $Text2 = #373737 $Text3 = #515151 $Text4 = #6b6b6b $TextError = #3d3d3d - $CloseButton = #b8b8b8 $CloseButtonHover = #008f00 - $SpinnerColor1 = #00a300 $SpinnerColor2 = rgba(70,186,78,0.9) - $ScrollBarBg = #d1d1d1 $ScrollBarThumb = GreenD $ScrollBarThumbHover = GreenL @@ -40,39 +36,31 @@ $TbarIconFilter = invert(100%) $FullScreenButton = #3d3d3d $FullScreenButtonHover = GreenD - $FilterBarBg = #fafafa $FilterBarText = #414141 $FilterBarTextHover = Black $FilterBarActive = GreenD - $SearchBoxBg = Grey - $DropDownBg = White $DropDownBgHover = Grey $DropDownTextHover = Black $DropDownText = #373737 $DropDownOpacity = 0.97 - $FilterBarIcon = $Text2 $FilterBarIconHover = GreenD $FilterBarIcon-PosterWidth = $Text4 - - $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9); + $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9) //Buttons $ButtonBg = #00a300 $ButtonBgHover = #00b700 $ButtonBgActive = #008f00 - $ButtonBgDisabled = #d8d8d8 - $ButtonBgOk = #27AE60 $ButtonBgWarning = #F15153 - $ButtonText = #fff $ButtonTextHover = #fff - + $ButtonImgInvert = 0 $ButtonRadius = 3px //Checkbox @@ -89,22 +77,17 @@ //TV Series $ShowBgColor1 = $BgColor1 $ShowBgColor2 = $BgColor2 - $EpisodeDetailsBg = $BgColor1 - $ShowText1 = $Text1 $ShowText2 = $Text2 $ShowOddHighlight = lighten($ShowBgColor1,50%) $ShowOddHighlightOp = 0.1 - $SaisonListText = Black $EpisodeListText = $Text2 - $EpisodeSelectorBg = GreenD $EpisodeSelectorHover = darken($ShowBgColor2,10%) $EpisodeSelectorHoverTran = darken($EpisodeSelectorHover,43%) $EpisodeSelectorText = $ButtonText - $ShowWatchedIcon_false = rgba(#1d1d1d,0.3) $ShowWatchedIcon_hover = rgba(#1d1d1d,0.7) $ShowWatchedIcon_true = rgba(#1d1d1d,0.95) @@ -117,16 +100,12 @@ //Settings $SettingsCategoriesText = GreenD $SettingsSeparator = #aaa - $InputBoxBg = #d8d8d8 $InputBoxText = $Text1 - $SettingsText1 = $Text1 $SettingsText2 = $Text4 - $SettingsButtonText = $ButtonText $SettingsButtonTextHover = $ButtonText - $QualitySelectorBg = $ButtonBg $QualitySelectorText = $ButtonText @@ -138,10 +117,8 @@ $NotificationOrange = #f07f53 $NotificationError = #f15153 $NotificationBorderColor = #000 - $NotificationBtn = #000 $NotificationBtnText = #fff - $NotifAlertBg = #000 $NotifAlertText = #fff @@ -154,7 +131,6 @@ //Player $PlayerColor = GreenL - // OFFICIAL POPCORN-THEME: LIGHT - END @import 'views/app' diff --git a/src/app/styl/Sebastiaans_-_Black_&_Red_theme.styl b/src/app/styl/Sebastiaans_-_Black_&_Red_theme.styl index b5b1c50bc5..9548a8ce85 100644 --- a/src/app/styl/Sebastiaans_-_Black_&_Red_theme.styl +++ b/src/app/styl/Sebastiaans_-_Black_&_Red_theme.styl @@ -16,19 +16,15 @@ //Main app $BgColor1 = Black $BgColor2 = lighten(Black,5%) - $Text1 = #fff $Text2 = #C9C9C9 $Text3 = #939597 $Text4 = #fff $TextError = #797979 - $CloseButton = #fff $CloseButtonHover = RedL - $SpinnerColor1 = RedM $SpinnerColor2 = RedD - $ScrollBarBg = #30333c $ScrollBarThumb = RedM $ScrollBarThumbHover = RedD @@ -39,39 +35,31 @@ $TbarIconFilter = none $FullScreenButton = #999 $FullScreenButtonHover = RedL - $FilterBarBg = Black $FilterBarText = #e9e9e9 $FilterBarTextHover = #fff $FilterBarActive = RedL - $SearchBoxBg = #191818 - $DropDownBg = rgba(Black,0.9) $DropDownBgHover = rgba(RedL,0.15) $DropDownTextHover = #fff $DropDownText = #d9d9d9 $DropDownOpacity = 0.97 - $FilterBarIcon = $Text1 $FilterBarIconHover = RedD $FilterBarIcon-PosterWidth = #bababa - - $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9); + $TopBarShadow = 0px 6px 8px -4px rgba(0, 0, 0, .9) //Buttons $ButtonBg = RedL $ButtonBgHover = RedD $ButtonBgActive = RedD - $ButtonBgDisabled = #737577 - $ButtonBgOk = #27AE60 $ButtonBgWarning = #F15153 - $ButtonText = #fff $ButtonTextHover = #fff - + $ButtonImgInvert = 0 $ButtonRadius = 3px //Checkbox @@ -88,26 +76,20 @@ //TV Series $ShowBgColor1 = $BgColor1 $ShowBgColor2 = $BgColor2 - $EpisodeDetailsBg = $BgColor1 - $ShowText1 = $Text1 $ShowText2 = $Text2 $ShowOddHighlight = lighten($ShowBgColor1,50%) $ShowOddHighlightOp = 0.05 - $SaisonListText = $Text1 $EpisodeListText = $Text2 - - $EpisodeSelectorBg = darken(#e3bd0c,2%) + $EpisodeSelectorBg = darken(RedD,2%) $EpisodeSelectorHover = #26272d $EpisodeSelectorHoverTran = lighten($EpisodeSelectorHover,43%) $EpisodeSelectorText = $ButtonText - $ShowWatchedIcon_false = rgba(#fff,0.2) $ShowWatchedIcon_hover = rgba(#fff,0.4) $ShowWatchedIcon_true = #fff - $QualitySelectorBg = $ButtonBg $QualitySelectorText = $ButtonText @@ -119,13 +101,10 @@ //Settings $SettingsCategoriesText = RedD $SettingsSeparator = #333 - $InputBoxBg = #232324 $InputBoxText = $Text2 - $SettingsText1 = $Text2 $SettingsText2 = $Text3 - $SettingsButtonText = $ButtonText $SettingsButtonTextHover = $ButtonText @@ -137,10 +116,8 @@ $NotificationOrange = #f07f53 $NotificationError = #f15153 $NotificationBorderColor = #000 - $NotificationBtn = #000 $NotificationBtnText = #fff - $NotifAlertBg = #000 $NotifAlertText = #fff @@ -155,7 +132,6 @@ //Player $PlayerColor = RedL - // THEME: BLACK & RED - END @import 'views/app' diff --git a/src/app/styl/views/about.styl b/src/app/styl/views/about.styl index 98d9db8b89..571c3721b0 100644 --- a/src/app/styl/views/about.styl +++ b/src/app/styl/views/about.styl @@ -61,6 +61,8 @@ a cursor pointer color #fff + margin -3px -2px + padding 3px &:hover color $ButtonBgHover @@ -88,8 +90,8 @@ .text-about line-height 1.2em - text-align: justify - text-align-last: center + text-align justify + text-align-last center margin 40px auto max-width 42em font-size 1em @@ -120,22 +122,6 @@ background url(../images/icons/icon-popcorn.png) no-repeat center background-size contain - a.twitter_icon - background url(../images/icons/icon-twitter.png) no-repeat center - background-size contain - - a.facebook_icon - background url(../images/icons/icon-facebook.png) no-repeat center - background-size contain - - a.google_icon - background url(../images/icons/icon-google.png) no-repeat center - background-size contain - - a.stash_icon - background url(../images/icons/icon-stash.png) no-repeat center - background-size contain - a.ci_icon background url(../images/icons/icon-ci.png) no-repeat center background-size contain @@ -144,10 +130,6 @@ background url(../images/icons/icon-github.png) no-repeat center background-size contain - a.gitlab_icon - background url(../images/icons/icon-gitlab.png) no-repeat center - background-size contain - a.blog_icon background url(../images/icons/icon-blog.png) no-repeat center background-size contain diff --git a/src/app/styl/views/app.styl b/src/app/styl/views/app.styl index 95d6168e2c..e2da392275 100644 --- a/src/app/styl/views/app.styl +++ b/src/app/styl/views/app.styl @@ -1,6 +1,4 @@ -// Disable IE Vendor Patches support-for-ie = false -// Only use Webkit vendor prefixes vendor-prefixes = webkit official @import 'nib' @@ -12,39 +10,29 @@ $FilterBarHeight = 35px $HeaderHeight = 65px $MovieListPadding = calc(100% - 67px) - @import 'fonts' @import 'misc' -@import 'bootstrap-theme' +@import 'bootstrap_theme' @import 'button' - @import 'player' @import 'videojs' - @import 'dropdowns' - @import 'main_window' @import 'initializing' @import 'title_bar' -@import 'windows-titlebar' +@import 'windows_titlebar' @import 'filter_bar' - -@import 'browser/list' -@import 'browser/item' +@import 'list' +@import 'item' @import 'movie_detail' @import 'movie_error' @import 'show_detail' -@import 'torrent-list' - +@import 'torrent_list' @import 'about' -@import 'vpn' -@import 'help' @import 'keyboard' @import 'file_selector' @import 'torrent_collection' - @import 'settings_container' @import 'loading' @import 'notification' - @import 'seedbox' diff --git a/src/app/styl/views/bootstrap-theme.styl b/src/app/styl/views/bootstrap-theme.styl deleted file mode 100644 index e221bd08ba..0000000000 --- a/src/app/styl/views/bootstrap-theme.styl +++ /dev/null @@ -1,87 +0,0 @@ -.nav - font-size: 0.8em - -.header_icon - font-size: 20px - color: $Text3 //add onhover color of $FilterBarActive later - -ul.nav-hor > li - float: left - -.dropdown-menu - background-color: $DropDownBg - opacity $DropDownOpacity - - & > li > a - transition: all 0.2s - color: $DropDownText - opacity 1 - - &.active - color: $DropDownTextHover - background-color: $DropDownBgHover - background-image: none - border-left: 4px solid $FilterBarText - - &:focus, - &:hover - color: $DropDownTextHover - background-color: $DropDownBgHover - background-image: none - border-left: 4px solid $FilterBarActive - -.playerchoice - padding-left 5px - margin-left 8px - margin-right -5px - border-left 1px solid rgba(255,255,255,.2) - - img - width 20px - height 20px - margin 7.5px 2px - float left - - &:after - content '' - width 30px - height 100% - top 0 - right 0 - position absolute - -.playerchoicemenu - font-size 1em - text-align left - left auto - right -2px - - & > li > a - padding-left 10px - padding-right 25px - text-overflow ellipsis - overflow hidden - max-width 200px - - img - height 20px - width 20px - position absolute - right 3px - -webkit-filter: $PngLogo - -.playerchoicehelp - top -7px - right -16px - position absolute - opacity 0.2 - transition opacity 0.4s ease - - &:hover - opacity 0.97 - -.splayerlist - display inline-block - width 420px - line-height 20px - padding 4px 0px 14px diff --git a/src/app/styl/views/bootstrap_theme.styl b/src/app/styl/views/bootstrap_theme.styl new file mode 100644 index 0000000000..951aac1218 --- /dev/null +++ b/src/app/styl/views/bootstrap_theme.styl @@ -0,0 +1,118 @@ +.nav + font-size 0.8em + +.header_icon + font-size 20px + color $Text3 + +ul.nav-hor > li + float left + +.dropdown-menu + background-color $DropDownBg + opacity $DropDownOpacity + + & > li > a + transition all 0.2s + color $DropDownText + opacity 1 + padding 4px 20px + + &.active + color $DropDownTextHover + background-color $DropDownBgHover + background-image none + border-left 4px solid $FilterBarText + + &:focus, + &:hover + color $DropDownTextHover + background-color $DropDownBgHover + background-image none + border-left 4px solid $FilterBarActive + +.playerchoice + padding-left 5px + margin-left 8px + margin-right -5px + border-left 1px solid rgba(255,255,255,.2) + + img + width 20px + height 20px + margin 7.5px 2px + float left + filter invert($ButtonImgInvert) + + &:after + content '' + width 30px + height 100% + top 0 + right 0 + position absolute + +.playerchoicemenu + font-size 1em + text-align left + left auto + right -2px + + & > li > a + padding-left 10px + padding-right 25px + text-overflow ellipsis + overflow hidden + max-width 200px + + img + height 20px + width 20px + position absolute + right 3px + -webkit-filter $PngLogo + + .playerchoicetoolbar + background $DropDownBg + position absolute + width 50px + height 22px + top -26px + right 0px + border-radius 30px + + .playerchoicerefresh + top 3px + left 6px + padding 2px + position absolute + color $DropDownText + opacity 0.3 + transition color 0.4s ease, opacity 0.4s ease + + &:hover + color $DropDownTextHover + opacity 0.97 + + &.spin + color $DropDownTextHover + opacity 0.97 + + .playerchoicehelp + top 3px + right 6px + padding 2px + position absolute + color $DropDownText + opacity 0.3 + transition color 0.4s ease, opacity 0.4s ease + + &:hover + color $DropDownTextHover + opacity 0.97 + +.splayerlist + display inline-block + width 420px + line-height 20px + padding 4px 0px 14px diff --git a/src/app/styl/views/browser/list.styl b/src/app/styl/views/browser/list.styl deleted file mode 100644 index b31b2ac35a..0000000000 --- a/src/app/styl/views/browser/list.styl +++ /dev/null @@ -1,109 +0,0 @@ -.list - height: 100% - width: calc(100% - 5px) - fixed: top left - text-align: center - scrollable() - - &::-webkit-scrollbar-track - margin-top: $HeaderHeight - margin-bottom 5px - - .items_show - padding-top: $HeaderHeight - -webkit-user-select: none; - text-align: left - display: flex - flex-direction: row - flex-wrap: wrap - justify-content: space-between - align-content: flex-start - align-items: flex-start - width: calc(50% - 5px) - height: 100% - float: left - background: rgba(138, 138, 138, 0.14) - scrollable() - - &::-webkit-scrollbar-track - margin-top: $HeaderHeight - - .title_history - color: $Text1 - padding: 25px 10px 10px - font-size: 1.2em - text-align: left - - .items - padding-top: 0 - - .items_movie - padding-top: $HeaderHeight - -webkit-user-select: none; - text-align: left - display: flex - flex-direction: row - flex-wrap: wrap - justify-content: space-between - align-content: flex-start - align-items: flex-start - width: calc(50% - 5px) - height: 100% - float: left - scrollable() - - &::-webkit-scrollbar-track - margin-top: $HeaderHeight - - .title_history - color: $Text1 - padding: 25px 10px 10px - font-size: 1.2em - text-align: left - - .items - padding-top: 0 - .items - padding-top: $HeaderHeight - -webkit-user-select: none; - text-align: left - display: flex - flex-direction: row - flex-wrap: wrap - justify-content: space-between - align-content: flex-start - align-items: flex-start - width: calc(100% - 5px) - will-change: transform, scroll-position - - .error - font-size: 1.5em; - text-align: center; - margin-top: 180px; - width: 80% - margin-left: 10% - position: absolute - color: $TextError; - font-weight: bold; - - > .spinner - position: fixed; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.5) center center no-repeat; - pointer-events: all; - z-index: 1; - - .loading-container - margin: 50vh auto 0px - opacity: .8; -.default-frame - .list - &::-webkit-scrollbar-track - margin-top $FilterBarHeight - .items_show - &::-webkit-scrollbar-track - margin-top $FilterBarHeight - .items_movie - &::-webkit-scrollbar-track - margin-top $FilterBarHeight diff --git a/src/app/styl/views/button.styl b/src/app/styl/views/button.styl index a89b36a108..ead8fb1903 100644 --- a/src/app/styl/views/button.styl +++ b/src/app/styl/views/button.styl @@ -1,28 +1,28 @@ .button - cursor: pointer - height: 35px - margin-right: 15px - border-radius: $ButtonRadius - background-clip: padding-box - background-color: $ButtonBg - padding: 0 15px - transition: background-color 0.5s - color: $ButtonText - font-family: $MainFont - font-smoothing: antialiased - text-align: center - font-size: 12px - line-height: 34px + cursor pointer + height 35px + margin-right 15px + border-radius $ButtonRadius + background-clip padding-box + background-color $ButtonBg + padding 0 15px + transition background-color 0.5s + color $ButtonText + font-family $MainFont + font-smoothing antialiased + text-align center + font-size 12px + line-height 34px &:hover - background: $ButtonBgHover - text-decoration: none + background $ButtonBgHover + text-decoration none &:active - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + background $ButtonBgActive &.disabled - cursor: not-allowed - opacity: 0.2 - filter: grayscale(100%) + cursor not-allowed + opacity 0.2 + filter grayscale(100%) diff --git a/src/app/styl/views/dropdowns.styl b/src/app/styl/views/dropdowns.styl index c511d44482..c6cc8d9583 100644 --- a/src/app/styl/views/dropdowns.styl +++ b/src/app/styl/views/dropdowns.styl @@ -1,246 +1,246 @@ .lang-dropdown - display: flex - align-items: center - cursor: pointer - height: 35px - padding: 0 15px - color: #fff - font-family: $MainFont - font-smoothing: antialiased - text-align: center - font-size: 12px - line-height: 34px - transition: background-color 0.5s + display flex + align-items center + cursor pointer + height 35px + padding 0 15px + color #fff + font-family $MainFont + font-smoothing antialiased + text-align center + font-size 12px + line-height 34px + transition background-color 0.5s .lang-name - margin-right: auto + margin-right auto .open .lang-dropdown - background: $ButtonBg - border-radius: $ButtonRadius - background-clip: padding-box + background $ButtonBg + border-radius $ButtonRadius + background-clip padding-box .flag-container - display: flex - flex-wrap: wrap - max-width: 100% - margin-left: 5px + display flex + flex-wrap wrap + max-width 100% + margin-left 5px .flag &:hover - -webkit-filter: drop-shadow(0px 0px 2px #fff) brightness(1.4) + -webkit-filter drop-shadow(0px 0px 2px #fff) brightness(1.4) .flag - margin: 6px 4px - background-image: url("../images/flags/question.svg") - background-size: 24px 24px - background-position: center - cursor: pointer - width: 22px - height: 16px + margin 6px 4px + background-image url("../images/icons/flag-question.svg") + background-size 24px 24px + background-position center + cursor pointer + width 22px + height 16px &.none - background-image: url("../images/flags/none.svg") + background-image url("../images/icons/flag-none.svg") &.toggle - top: -6px - border-radius: 0 - background-color: transparent + top -6px + border-radius 0 + background-color transparent &.ar - background-image: url("/node_modules/flag-icons/flags/4x3/ae.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ae.svg") &.hy - background-image: url("/node_modules/flag-icons/flags/4x3/am.svg") + background-image url("/node_modules/flag-icons/flags/4x3/am.svg") &.bn - background-image: url("/node_modules/flag-icons/flags/4x3/bd.svg") + background-image url("/node_modules/flag-icons/flags/4x3/bd.svg") &.bs - background-image: url("/node_modules/flag-icons/flags/4x3/ba.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ba.svg") &.pt-br - background-image: url("/node_modules/flag-icons/flags/4x3/br.svg") + background-image url("/node_modules/flag-icons/flags/4x3/br.svg") &.bg - background-image: url("/node_modules/flag-icons/flags/4x3/bg.svg") + background-image url("/node_modules/flag-icons/flags/4x3/bg.svg") &.zh - background-image: url("/node_modules/flag-icons/flags/4x3/cn.svg") + background-image url("/node_modules/flag-icons/flags/4x3/cn.svg") &.hr - background-image: url("/node_modules/flag-icons/flags/4x3/hr.svg") + background-image url("/node_modules/flag-icons/flags/4x3/hr.svg") &.cs - background-image: url("/node_modules/flag-icons/flags/4x3/cz.svg") + background-image url("/node_modules/flag-icons/flags/4x3/cz.svg") &.da - background-image: url("/node_modules/flag-icons/flags/4x3/dk.svg") + background-image url("/node_modules/flag-icons/flags/4x3/dk.svg") &.nl - background-image: url("/node_modules/flag-icons/flags/4x3/nl.svg") + background-image url("/node_modules/flag-icons/flags/4x3/nl.svg") &.en - background-image: url("/node_modules/flag-icons/flags/4x3/gb.svg") + background-image url("/node_modules/flag-icons/flags/4x3/gb.svg") &.et - background-image: url("/node_modules/flag-icons/flags/4x3/ee.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ee.svg") &.fa - background-image: url("/node_modules/flag-icons/flags/4x3/ir.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ir.svg") &.fi - background-image: url("/node_modules/flag-icons/flags/4x3/fi.svg") + background-image url("/node_modules/flag-icons/flags/4x3/fi.svg") &.fr - background-image: url("/node_modules/flag-icons/flags/4x3/fr.svg") + background-image url("/node_modules/flag-icons/flags/4x3/fr.svg") &.de - background-image: url("/node_modules/flag-icons/flags/4x3/de.svg") + background-image url("/node_modules/flag-icons/flags/4x3/de.svg") &.el - background-image: url("/node_modules/flag-icons/flags/4x3/gr.svg") + background-image url("/node_modules/flag-icons/flags/4x3/gr.svg") &.he - background-image: url("/node_modules/flag-icons/flags/4x3/il.svg") + background-image url("/node_modules/flag-icons/flags/4x3/il.svg") &.hu - background-image: url("/node_modules/flag-icons/flags/4x3/hu.svg") + background-image url("/node_modules/flag-icons/flags/4x3/hu.svg") &.it - background-image: url("/node_modules/flag-icons/flags/4x3/it.svg") + background-image url("/node_modules/flag-icons/flags/4x3/it.svg") &.id - background-image: url("/node_modules/flag-icons/flags/4x3/id.svg") + background-image url("/node_modules/flag-icons/flags/4x3/id.svg") &.ja - background-image: url("/node_modules/flag-icons/flags/4x3/jp.svg") + background-image url("/node_modules/flag-icons/flags/4x3/jp.svg") &.ka - background-image: url("/node_modules/flag-icons/flags/4x3/ge.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ge.svg") &.ko - background-image: url("/node_modules/flag-icons/flags/4x3/kr.svg") + background-image url("/node_modules/flag-icons/flags/4x3/kr.svg") &.lv - background-image: url("/node_modules/flag-icons/flags/4x3/lv.svg") + background-image url("/node_modules/flag-icons/flags/4x3/lv.svg") &.lt - background-image: url("/node_modules/flag-icons/flags/4x3/lt.svg") + background-image url("/node_modules/flag-icons/flags/4x3/lt.svg") &.mk - background-image: url("/node_modules/flag-icons/flags/4x3/mk.svg") + background-image url("/node_modules/flag-icons/flags/4x3/mk.svg") &.ms - background-image: url("/node_modules/flag-icons/flags/4x3/my.svg") + background-image url("/node_modules/flag-icons/flags/4x3/my.svg") &.mt - background-image: url("/node_modules/flag-icons/flags/4x3/mt.svg") + background-image url("/node_modules/flag-icons/flags/4x3/mt.svg") &.no - background-image: url("/node_modules/flag-icons/flags/4x3/no.svg") + background-image url("/node_modules/flag-icons/flags/4x3/no.svg") &.nb - background-image: url("/node_modules/flag-icons/flags/4x3/no.svg") + background-image url("/node_modules/flag-icons/flags/4x3/no.svg") &.nn - background-image: url("/node_modules/flag-icons/flags/4x3/no.svg") + background-image url("/node_modules/flag-icons/flags/4x3/no.svg") &.pl - background-image: url("/node_modules/flag-icons/flags/4x3/pl.svg") + background-image url("/node_modules/flag-icons/flags/4x3/pl.svg") &.pt - background-image: url("/node_modules/flag-icons/flags/4x3/pt.svg") + background-image url("/node_modules/flag-icons/flags/4x3/pt.svg") &.ro - background-image: url("/node_modules/flag-icons/flags/4x3/ro.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ro.svg") &.ru - background-image: url("/node_modules/flag-icons/flags/4x3/ru.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ru.svg") &.sr - background-image: url("/node_modules/flag-icons/flags/4x3/rs.svg") + background-image url("/node_modules/flag-icons/flags/4x3/rs.svg") &.sk - background-image: url("/node_modules/flag-icons/flags/4x3/sk.svg") + background-image url("/node_modules/flag-icons/flags/4x3/sk.svg") &.sl - background-image: url("/node_modules/flag-icons/flags/4x3/si.svg") + background-image url("/node_modules/flag-icons/flags/4x3/si.svg") &.es - background-image: url("/node_modules/flag-icons/flags/4x3/es.svg") + background-image url("/node_modules/flag-icons/flags/4x3/es.svg") &.sv - background-image: url("/node_modules/flag-icons/flags/4x3/se.svg") + background-image url("/node_modules/flag-icons/flags/4x3/se.svg") &.th - background-image: url("/node_modules/flag-icons/flags/4x3/th.svg") + background-image url("/node_modules/flag-icons/flags/4x3/th.svg") &.tr - background-image: url("/node_modules/flag-icons/flags/4x3/tr.svg") + background-image url("/node_modules/flag-icons/flags/4x3/tr.svg") &.uk - background-image: url("/node_modules/flag-icons/flags/4x3/ua.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ua.svg") &.vi - background-image: url("/node_modules/flag-icons/flags/4x3/vn.svg") + background-image url("/node_modules/flag-icons/flags/4x3/vn.svg") &.sq - background-image: url("/node_modules/flag-icons/flags/4x3/al.svg") + background-image url("/node_modules/flag-icons/flags/4x3/al.svg") &.am - background-image: url("/node_modules/flag-icons/flags/4x3/et.svg") + background-image url("/node_modules/flag-icons/flags/4x3/et.svg") &.az - background-image: url("/node_modules/flag-icons/flags/4x3/az.svg") + background-image url("/node_modules/flag-icons/flags/4x3/az.svg") &.be - background-image: url("/node_modules/flag-icons/flags/4x3/by.svg") + background-image url("/node_modules/flag-icons/flags/4x3/by.svg") &.es-ar - background-image: url("/node_modules/flag-icons/flags/4x3/ar.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ar.svg") &.es-mx - background-image: url("/node_modules/flag-icons/flags/4x3/mx.svg") + background-image url("/node_modules/flag-icons/flags/4x3/mx.svg") &.fj - background-image: url("/node_modules/flag-icons/flags/4x3/fj.svg") + background-image url("/node_modules/flag-icons/flags/4x3/fj.svg") &.ga - background-image: url("/node_modules/flag-icons/flags/4x3/ie.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ie.svg") &.gn - background-image: url("/node_modules/flag-icons/flags/4x3/py.svg") + background-image url("/node_modules/flag-icons/flags/4x3/py.svg") &.hi - background-image: url("/node_modules/flag-icons/flags/4x3/in.svg") + background-image url("/node_modules/flag-icons/flags/4x3/in.svg") &.ho - background-image: url("/node_modules/flag-icons/flags/4x3/pg.svg") + background-image url("/node_modules/flag-icons/flags/4x3/pg.svg") &.ht - background-image: url("/node_modules/flag-icons/flags/4x3/ht.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ht.svg") &.is - background-image: url("/node_modules/flag-icons/flags/4x3/is.svg") + background-image url("/node_modules/flag-icons/flags/4x3/is.svg") &.kk - background-image: url("/node_modules/flag-icons/flags/4x3/kz.svg") + background-image url("/node_modules/flag-icons/flags/4x3/kz.svg") &.km - background-image: url("/node_modules/flag-icons/flags/4x3/kh.svg") + background-image url("/node_modules/flag-icons/flags/4x3/kh.svg") &.lb - background-image: url("/node_modules/flag-icons/flags/4x3/lu.svg") + background-image url("/node_modules/flag-icons/flags/4x3/lu.svg") &.lo - background-image: url("/node_modules/flag-icons/flags/4x3/la.svg") + background-image url("/node_modules/flag-icons/flags/4x3/la.svg") &.mg - background-image: url("/node_modules/flag-icons/flags/4x3/mg.svg") + background-image url("/node_modules/flag-icons/flags/4x3/mg.svg") &.mi - background-image: url("/node_modules/flag-icons/flags/4x3/nz.svg") + background-image url("/node_modules/flag-icons/flags/4x3/nz.svg") &.mn - background-image: url("/node_modules/flag-icons/flags/4x3/mn.svg") + background-image url("/node_modules/flag-icons/flags/4x3/mn.svg") &.my - background-image: url("/node_modules/flag-icons/flags/4x3/mm.svg") + background-image url("/node_modules/flag-icons/flags/4x3/mm.svg") &.na - background-image: url("/node_modules/flag-icons/flags/4x3/nr.svg") + background-image url("/node_modules/flag-icons/flags/4x3/nr.svg") &.ne - background-image: url("/node_modules/flag-icons/flags/4x3/np.svg") + background-image url("/node_modules/flag-icons/flags/4x3/np.svg") &.ny - background-image: url("/node_modules/flag-icons/flags/4x3/nw.svg") + background-image url("/node_modules/flag-icons/flags/4x3/nw.svg") &.ps - background-image: url("/node_modules/flag-icons/flags/4x3/af.svg") + background-image url("/node_modules/flag-icons/flags/4x3/af.svg") &.rm - background-image: url("/node_modules/flag-icons/flags/4x3/ch.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ch.svg") &.rn - background-image: url("/node_modules/flag-icons/flags/4x3/bi.svg") + background-image url("/node_modules/flag-icons/flags/4x3/bi.svg") &.rw - background-image: url("/node_modules/flag-icons/flags/4x3/rw.svg") + background-image url("/node_modules/flag-icons/flags/4x3/rw.svg") &.si - background-image: url("/node_modules/flag-icons/flags/4x3/lk.svg") + background-image url("/node_modules/flag-icons/flags/4x3/lk.svg") &.sm - background-image: url("/node_modules/flag-icons/flags/4x3/ws.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ws.svg") &.sn - background-image: url("/node_modules/flag-icons/flags/4x3/zw.svg") + background-image url("/node_modules/flag-icons/flags/4x3/zw.svg") &.so - background-image: url("/node_modules/flag-icons/flags/4x3/so.svg") + background-image url("/node_modules/flag-icons/flags/4x3/so.svg") &.tg - background-image: url("/node_modules/flag-icons/flags/4x3/tj.svg") + background-image url("/node_modules/flag-icons/flags/4x3/tj.svg") &.ti - background-image: url("/node_modules/flag-icons/flags/4x3/er.svg") + background-image url("/node_modules/flag-icons/flags/4x3/er.svg") &.tk - background-image: url("/node_modules/flag-icons/flags/4x3/tm.svg") + background-image url("/node_modules/flag-icons/flags/4x3/tm.svg") &.ua - background-image: url("/node_modules/flag-icons/flags/4x3/ua.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ua.svg") &.ur - background-image: url("/node_modules/flag-icons/flags/4x3/pk.svg") + background-image url("/node_modules/flag-icons/flags/4x3/pk.svg") &.uz - background-image: url("/node_modules/flag-icons/flags/4x3/uz.svg") + background-image url("/node_modules/flag-icons/flags/4x3/uz.svg") &.gl - background-image: url("/node_modules/flag-icons/flags/4x3/es-ga.svg") + background-image url("/node_modules/flag-icons/flags/4x3/es-ga.svg") &.ca - background-image: url("/node_modules/flag-icons/flags/4x3/es-ca.svg") + background-image url("/node_modules/flag-icons/flags/4x3/es-ca.svg") &.oc - background-image: url("/node_modules/flag-icons/flags/4x3/es-ca.svg") + background-image url("/node_modules/flag-icons/flags/4x3/es-ca.svg") &.tl - background-image: url("/node_modules/flag-icons/flags/4x3/ph.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ph.svg") &.br - background-image: url("/node_modules/flag-icons/flags/4x3/fr.svg") + background-image url("/node_modules/flag-icons/flags/4x3/fr.svg") &.ig - background-image: url("/node_modules/flag-icons/flags/4x3/ng.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ng.svg") &.tt - background-image: url("/node_modules/flag-icons/flags/4x3/ru.svg") + background-image url("/node_modules/flag-icons/flags/4x3/ru.svg") &.ml - background-image: url("/node_modules/flag-icons/flags/4x3/in.svg") + background-image url("/node_modules/flag-icons/flags/4x3/in.svg") &.te - background-image: url("/node_modules/flag-icons/flags/4x3/in.svg") + background-image url("/node_modules/flag-icons/flags/4x3/in.svg") &.or - background-image: url("/node_modules/flag-icons/flags/4x3/in.svg") + background-image url("/node_modules/flag-icons/flags/4x3/in.svg") &.kn - background-image: url("/node_modules/flag-icons/flags/4x3/in.svg") + background-image url("/node_modules/flag-icons/flags/4x3/in.svg") &.ea - background-image: url("/node_modules/flag-icons/flags/4x3/es.svg") + background-image url("/node_modules/flag-icons/flags/4x3/es.svg") &.sp - background-image: url("/node_modules/flag-icons/flags/4x3/es.svg") + background-image url("/node_modules/flag-icons/flags/4x3/es.svg") &.ze - background-image: url("/node_modules/flag-icons/flags/4x3/cn.svg") + background-image url("/node_modules/flag-icons/flags/4x3/cn.svg") &.zt - background-image: url("/node_modules/flag-icons/flags/4x3/cn.svg") + background-image url("/node_modules/flag-icons/flags/4x3/cn.svg") diff --git a/src/app/styl/views/file_selector.styl b/src/app/styl/views/file_selector.styl index ea69478ea3..66d6043ab5 100644 --- a/src/app/styl/views/file_selector.styl +++ b/src/app/styl/views/file_selector.styl @@ -8,42 +8,60 @@ opacity 1 background-position 50% 50% + .file-selector-backdrop + position absolute + width 100% + height 100% + background-repeat no-repeat + background-position-x 50% + background-position-y 50% + background-size cover + filter blur(60px) brightness(0.7) + margin-top 32px + + .file-selector-backdrop-overlay + width 100% + height 100% + position absolute + opacity 0.7 + background-color $ShowBgColor1 + .button - position: absolute - right: 16.2% - cursor: pointer - height: 35px - margin-top: 15px - border-radius: $ButtonRadius - background-clip: padding-box - background-color: $ButtonBg - padding: 0 15px - transition: background-color 0.5s - color: $ButtonText - font-family: $MainFont - font-smoothing: antialiased - text-align: center - font-size: 12px - line-height: 34px + position absolute + right 16.2% + cursor pointer + height 35px + margin-top 15px + border-radius $ButtonRadius + background-clip padding-box + background-color $ButtonBg + padding 0 15px + transition background-color 0.5s + color $ButtonText + font-family $MainFont + font-smoothing antialiased + text-align center + font-size 12px + line-height 34px &:hover - background: $ButtonBgHover - text-decoration: none + background $ButtonBgHover + text-decoration none &:active - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + background $ButtonBgActive .playerchoice - padding-left: 0px - margin: 0 - border: 0 + padding-left 0px + margin 0 + border 0 &.store-torrent - right: initial - margin-left: 17% - margin-top: 15px - position: absolute + right initial + margin-left 17% + margin-top 15px + position absolute &.disabled background-color $ButtonBgDisabled @@ -79,11 +97,12 @@ content '\f071' color $WarningColor font-family "Font Awesome 6 Free" - font-weight: 900 + font-weight 900 font-size 16px padding-right 8px .content + position relative margin 0 auto 32px auto width calc(66% - 5px) height 56.5% @@ -100,36 +119,48 @@ text-align left cursor pointer color $SettingsText1 + height 40px + margin-top 2px &:nth-child(odd) - background $ShowBgColor2 + background rgba($ShowOddHighlight, $ShowOddHighlightOp) a color $EpisodeListText text-decoration blink width 100% display block - padding 12px 0 13px 24px - margin-top 2px - margin-bottom 2px + padding 12px 160px 13px 20px transition opacity .1s ease-in + overflow hidden + text-overflow ellipsis + white-space nowrap + position absolute + z-index 1 &:hover - background $EpisodeSelectorHover + background rgba($EpisodeSelectorHoverTran,20%) i float right - margin -29px 30px 0 0 + margin 2px 13px 2px 1px + border-radius 50% opacity 0.4 transition all .5s font-size 14px + padding 10px + position relative + z-index 2 &:hover opacity 1 + ~ a + background rgba($EpisodeSelectorHoverTran,20%) + span float right - margin -28px 30px 0 0 + margin 13px 24px 0 0 opacity 0.4 pointer-events none font-size 14px diff --git a/src/app/styl/views/filter_bar.styl b/src/app/styl/views/filter_bar.styl index 0f2c64e168..3963016faa 100644 --- a/src/app/styl/views/filter_bar.styl +++ b/src/app/styl/views/filter_bar.styl @@ -1,136 +1,137 @@ .vpn-connected - color: #38A169 !important + color #38A169 !important .vpn-disconnected - color: #E53E3E !important + color #E53E3E !important .filter-bar - z-index: 10 - width: 100% - opacity: .97 - height: 35px - background-color: $FilterBarBg - -webkit-user-select: none - position: absolute - top: $TitleHeight - height: $FilterBarHeight - box-shadow: $TopBarShadow + z-index 10 + width 100% + opacity .97 + height 35px + background-color $FilterBarBg + -webkit-user-select none + position absolute + top $TitleHeight + height $FilterBarHeight + box-shadow $TopBarShadow .source - box-sizing: content-box - color: $FilterBarText - text-align: center - cursor: pointer - height: 20px - margin-top: 10px - padding: 0px 15px 1px 18px + box-sizing content-box + color $FilterBarText + text-align center + cursor pointer + height 20px + margin-top 10px + padding 0px 15px 1px 18px &:hover - color: $FilterBarTextHover + color $FilterBarTextHover &.active - border-bottom: 4px solid $FilterBarActive + border-bottom 4px solid $FilterBarActive .nav.filters - float: left - margin-left: 10px + float left + margin-left 10px .nav.right - margin-right: 5px + margin-right 5px .filter - padding: 10px 0 0 - margin-left: 20px + padding 10px 0 0 + margin-left 20px & > a - display: inline-block - padding: 0 - color: $FilterBarText - background-color: transparent !important + display inline-block + padding 0 + color $FilterBarText + background-color transparent !important &:hover - color: $FilterBarTextHover + color $FilterBarTextHover .value - color: $FilterBarActive - padding-left: 10px + color $FilterBarActive + padding-left 10px .dropdown-menu - font-size: 0.9em + font-size 0.9em scrollable() - max-height: 445px - margin-top: 11px - border-top-left-radius: 0 - border-top-right-radius: 0 + max-height 445px + margin-top 11px + border-top-left-radius 0 + border-top-right-radius 0 i - transition: color 0.5s - margin: 10px 5px 0 - color: $FilterBarIcon - font-size: 1.5em + transition color 0.5s + margin 8px 3px 0 4px + padding 2px + color $FilterBarIcon + font-size 1.5em &:hover - color: $FilterBarIconHover - cursor: pointer + color $FilterBarIconHover + cursor pointer &.active &.favorites - color: $FavoriteColor + color $FavoriteColor &:hover color darken($FavoriteColor, 10) transition all .5s &.watchlist - color: $FilterBarActive + color $FilterBarActive &.torrent-collection - color: $FilterBarActive + color $FilterBarActive &.about - color: $FilterBarIconHover + color $FilterBarIconHover &.vpn - color: $FilterBarIconHover + color $FilterBarIconHover &.seedbox - color: $FilterBarActive + color $FilterBarActive .clear - display: none + display none .search form &:before - content: '\f002' - font-family: "Font Awesome 6 Free" - font-weight: 900 - font-style: normal + content '\f002' + font-family "Font Awesome 6 Free" + font-weight 900 + font-style normal transition color 0.5s - color: $FilterBarIcon - position: absolute - top:11px - left: 8px - z-index: 2 - font-size: 1.4em + color $FilterBarIcon + position absolute + top 11px + left 8px + z-index 2 + font-size 1.4em &.edited .clear - display: block - font-weight: bold + display block + font-weight bold transition color 0.5s - color: $FilterBarIcon - position: absolute - top:8px - right: 5px - padding: 3px 5px - font-size: 1.2em + color $FilterBarIcon + position absolute + top 8px + right 5px + padding 3px 5px + font-size 1.2em &.edited input, input:focus, input.expanded - width: 190px - background-color: $SearchBoxBg - color: $FilterBarText - padding-left: 28px + width 190px + background-color $SearchBoxBg + color $FilterBarText + padding-left 28px &.edited, &:hover - cursor: pointer + cursor pointer &:before - color: $FilterBarIconHover + color $FilterBarIconHover input line-height normal @@ -152,13 +153,13 @@ transition width 0.5s &:focus - cursor: auto + cursor auto &:before - color: $FilterBarIconHover //this doesn't work for some reason + color $FilterBarIconHover &::-moz-placeholder, &::-webkit-input-placeholder - color: transparent + color transparent &:focus::-webkit-input-placeholder - color: rgba($FilterBarText,.7) + color rgba($FilterBarText,.7) diff --git a/src/app/styl/views/fonts.styl b/src/app/styl/views/fonts.styl index 9d426901bc..a18cb769d6 100644 --- a/src/app/styl/views/fonts.styl +++ b/src/app/styl/views/fonts.styl @@ -1,25 +1,24 @@ @font-face - font-family: 'Open Sans' - src: url(../fonts/OpenSans-Regular.woff) - font-weight: normal - font-style: normal + font-family 'Open Sans' + src url(../fonts/OpenSans-Regular.woff) + font-weight normal + font-style normal @font-face - font-family: 'Open Sans Bold' - src: url(../fonts/OpenSans-Bold.woff) - font-weight: normal - font-style: normal + font-family 'Open Sans Bold' + src url(../fonts/OpenSans-Bold.woff) + font-weight normal + font-style normal @font-face - font-family: 'Open Sans Semibold' - src: url(../fonts/OpenSans-Semibold.woff) - font-weight: normal - font-style: normal + font-family 'Open Sans Semibold' + src url(../fonts/OpenSans-Semibold.woff) + font-weight normal + font-style normal -@font-face { - font-family: 'VideoJS'; - src: url('../fonts/vjs.eot'); - src: url('../fonts/vjs.eot?#iefix') format('embedded-opentype'), url('../fonts/vjs.woff') format('woff'), url('../fonts/vjs.ttf') format('truetype'); - font-weight: normal; - font-style: normal; -} \ No newline at end of file +@font-face + font-family 'VideoJS' + src url('../fonts/vjs.eot') + src url('../fonts/vjs.eot?#iefix') format('embedded-opentype'), url('../fonts/vjs.woff') format('woff'), url('../fonts/vjs.ttf') format('truetype') + font-weight normal + font-style normal diff --git a/src/app/styl/views/help.styl b/src/app/styl/views/help.styl deleted file mode 100644 index 47bd979141..0000000000 --- a/src/app/styl/views/help.styl +++ /dev/null @@ -1,107 +0,0 @@ -.help-container - z-index 15 - height 100% - width 100% - position fixed - -webkit-user-select none - opacity 1 - - .overlay-content - height 100% - width 100% - position absolute - background $BgColor1 - opacity 0.95 - z-index -1 - - h1 - font-family $AlternateFont - font-weight bold - font-size 20px - - & + hr - margin-top: 10px - margin-bottom: 10px - - - .content - height: 100% - margin 0 auto - margin-top 60px - width 80% - color $Text1 - font-family $AlternateFont - font-size 15px - - .text-about - margin-top 55px - line-height 22px - margin-bottom 20px - position absolute - width 60% - - .did-you-know - display inline-block - text-align: center - line-height: 26px - vertical-align: middle - font-family: $AlternateFont - margin-bottom 10px - cursor pointer - - .title-dyk - font-family $AlternateFont - font-weight bold - color $Text1 - font-size: 20px - margin-right: 10px - - .icon-dyk - font-size: 22px - color: $Text1 - margin-right: 10px - - .randomized-dyk - font-size: 16px - - .help-outer - scrollable() - height: calc(100% - 185px); - padding-right 15px - text-align justify - - h2 - font-family $AlternateFont - font-weight bold - font-size 18px - line-height 22px - color $Text1 - margin-bottom 6px - margin-top 15px - - &.top - margin-top 5px - - p - font-family $AlternateFont - font-size 15px - line-height 20px - color $Text1 - opacity 0.9 - - li - margin-top 6px - line-height 18px - font-size 14px - font-family $AlternateFont - opacity 0.9 - - b - font-family $AlternateFont - font-weight: bold - - #in-app-reporter - cursor pointer - - em - font-size .8em diff --git a/src/app/styl/views/initializing.styl b/src/app/styl/views/initializing.styl index 1551e73920..921d5f3730 100644 --- a/src/app/styl/views/initializing.styl +++ b/src/app/styl/views/initializing.styl @@ -1,6 +1,6 @@ .init-container - position: absolute - -webkit-user-select: none + position absolute + -webkit-user-select none width 90% height 70.5% position absolute @@ -20,7 +20,6 @@ margin-top 3% background-color #bababa border-radius 13px - //padding 3px & > div width 0% @@ -28,7 +27,7 @@ height 5px border-radius 13px left 0px - transition: background-color 0.5s + transition background-color 0.5s .icon-begin display block @@ -42,7 +41,7 @@ height calc(11%) max-height 52px -webkit-filter $PngLogo - transition: -webkit-filter 0.5s + transition -webkit-filter 0.5s .init-geek-line margin 2% 0 @@ -50,7 +49,7 @@ width 100% text-align center font-family 23px - transition: color 0.5s + transition color 0.5s .heart color #e74c3c @@ -75,7 +74,7 @@ color $Text1 font-family $MainFont -webkit-font-smoothing antialiased - transition: color 0.5s, font-family 0.5s + transition color 0.5s, font-family 0.5s .init-status position relative @@ -83,7 +82,7 @@ font-family $MainFont -webkit-font-smoothing antialiased margin-top 1% - transition: color 0.5s, font-family 0.5s + transition color 0.5s, font-family 0.5s .init-expand color $Text1 @@ -98,7 +97,7 @@ -webkit-backface-visibility hidden position relative top 15% - transition: color 0.5s, font-family 0.5s + transition color 0.5s, font-family 0.5s #waiting-block position fixed @@ -147,7 +146,6 @@ -moz-animation spinoff .5s infinite linear -webkit-animation spinoff .5s infinite linear - #disclaimer-container .disclaimer height 100% position absolute @@ -314,7 +312,7 @@ border-color #398439 &:active - box-shadow: inset 0 1px 2px rgba(0,0,0,0.6) + box-shadow inset 0 1px 2px rgba(0,0,0,0.6) .btn-close display inline-block @@ -344,4 +342,26 @@ border-color #AC2925 &:active - box-shadow: inset 0 1px 2px rgba(0,0,0,0.6) + box-shadow inset 0 1px 2px rgba(0,0,0,0.6) + +@keyframes fullexpand + 0% + width 0px + 100% + width 100% + +@keyframes spin + 0% + transform rotate(0deg) + 100% + transform rotate(360deg) + +@keyframes spinoff + 0% + transform rotate(0deg) + 100% + transform rotate(-360deg) + +@keyframes blinker + 50% + opacity 0 diff --git a/src/app/styl/views/browser/item.styl b/src/app/styl/views/item.styl similarity index 52% rename from src/app/styl/views/browser/item.styl rename to src/app/styl/views/item.styl index b6bfdc9fc4..a534bd3b3e 100644 --- a/src/app/styl/views/browser/item.styl +++ b/src/app/styl/views/item.styl @@ -1,11 +1,11 @@ .item - display: inline-block; - margin: 10px - float: left - width: 134px - font-size: 0.8em + display inline-block + margin 10px + float left + width 134px + font-size 0.8em &.watched - opacity: 0.4 + opacity 0.4 .cover &.selected @@ -13,12 +13,12 @@ .cover background-image url(../images/posterholder.png) - background-size: 134px 196px - width: 134px - height: 196px - border-radius: $PosterRadius - box-shadow: $PosterShadow - cursor: pointer + background-size 134px 196px + width 134px + height 196px + border-radius $PosterRadius + box-shadow $PosterShadow + cursor pointer &.empty background-image none @@ -31,62 +31,84 @@ opacity 0 display none + &.selected + opacity 1 + display block + padding 88px 0 + border 2px solid rgba(0,0,0,0) + border-radius $PosterRadius + + .actions-watched, + .rating + visibility hidden + transition none + + &:hover > + .actions-watched, + .rating + visibility visible + &img position absolute left 0 &.fadein - opacity: 1 + opacity 1 &.cover-info-overlay padding 88px 0 background $PosterHoverOverlay - border: 2px solid $PosterHoverOverlayOpq border-radius $PosterRadius + &.selected + background none + + &:hover + background $PosterHoverOverlay + .actions-favorites - float: right - margin-top: -80px - margin-right: 7px - color: #FFFFFF - font-size: 1.4 em - -webkit-transition: all 0.5s - opacity: 0.3 + float right + margin-top -80px + margin-right 7px + color #FFFFFF + font-size 1.4 em + -webkit-transition all 0.5s + opacity 0.3 &.selected - color: $FavoriteColor - opacity: 1 + color $FavoriteColor + opacity 1 &:hover - cursor: pointer - color: $ButtonBgActive - opacity: 1 + cursor pointer + color $ButtonBgActive + opacity 1 .actions-watched - float: left - margin-top: -80px - margin-left: 7px - color: #FFFFFF - font-size: 1.4 em - -webkit-transition: all 0.5s - opacity: 0.3 + float left + margin-top -80px + margin-left 7px + color #FFFFFF + font-size 1.4 em + -webkit-transition all 0.5s + opacity 0.3 &:hover - cursor: pointer - color: $ButtonBgActive - opacity: 1 + cursor pointer + color $ButtonBgActive + opacity 1 &.selected - opacity: 1 + opacity 1 .rating - background: linear-gradient(to bottom, rgba(206,206,206,0) 0%,rgba(22,22,22,0.69) 69%,rgba(22,22,22,0.95) 100%) + background linear-gradient(to bottom, rgba(206,206,206,0) 0%,rgba(22,22,22,0.69) 69%,rgba(22,22,22,0.95) 100%) border-radius $PosterRadius bottom 0 display none height auto left 0 margin 0 - padding: 10px 5px 5px + padding 10px 5px 5px position absolute right 0 text-align left @@ -98,7 +120,7 @@ .rating-star color #ffc900 - padding-right: 0px + padding-right 0px vertical-align middle .rating-star-half @@ -129,49 +151,50 @@ &.selected > .cover .cover-overlay display block - animation: fadeBd 0.5s ease + animation fadeBd 0.5s ease .cover .cover-info-overlay border 2px solid $PosterHoverBorder - opacity: 1 - will-change: transform + opacity 1 + will-change transform .title - height: auto; - margin: 6px 0 4px; - color: $Text1 - max-width: 100% - overflow: hidden - text-overflow: ellipsis - white-space: nowrap - padding-bottom: 2px + height auto + margin 6px 0 4px + color $Text1 + max-width 100% + overflow hidden + text-overflow ellipsis + white-space nowrap + padding-bottom 2px .title2 - font-size: 0.85em - color: $Text1 - height: auto; - margin: -2px 0 3px; - overflow: hidden - text-overflow: ellipsis - white-space: nowrap - padding-bottom: 2px + font-size 0.85em + color $Text1 + height auto + margin -2px 0 3px + overflow hidden + text-overflow ellipsis + white-space nowrap + padding-bottom 2px .year - font-size: 0.85em - color: $Text4 - display: inline + font-size 0.85em + color $Text4 + display inline .seasons - font-size: 0.85em - color: $Text4 - display: inline - float: right - margin-top: 2px - -@keyframes fadeBd { - from { border-color: $PosterHoverOverlayOpq; } - to { border-color: $PosterHoverBorder; } -} + font-size 0.85em + color $Text4 + display inline + float right + margin-top 2px + +@keyframes fadeBd + from + border-color $PosterHoverOverlayOpq + to + border-color $PosterHoverBorder .load-more, .search-more @@ -215,31 +238,31 @@ .status-loadmore, .status-searchmore - position: absolute; - color: $Text1; - padding-bottom: 10px; - padding-top: 16px; - border-radius: 2px; - font-family: $MainFont, $AlternateFont; + position absolute + color $Text1 + padding-bottom 10px + padding-top 16px + border-radius 2px + font-family $MainFont, $AlternateFont opacity 0.3 text-align center - top: 50% - left: 50% - width: 90% + top 50% + left 50% + width 90% -webkit-transform translate(-50%, -50%) #searchtor - height: 2.8em - padding: 5px 0 48px - font-size: 1.4em + height 2.8em + padding 5px 0 48px + font-size 1.4em #searchtor_globe - padding-right: 10px + padding-right 10px #searchtor_mag - top: -5px - padding-left: 15px - -webkit-text-stroke: 2px $BgColor1 + top -5px + padding-left 15px + -webkit-text-stroke 2px $BgColor1 #overlay background $PosterHoverOverlay diff --git a/src/app/styl/views/keyboard.styl b/src/app/styl/views/keyboard.styl index e0d57f8f5b..042483b773 100644 --- a/src/app/styl/views/keyboard.styl +++ b/src/app/styl/views/keyboard.styl @@ -16,15 +16,14 @@ h1 font-family $AlternateFont - font-weight: bold; + font-weight bold font-size 20px & + hr - margin-top: 10px; - + margin-top 10px .content - height: 100% + height 100% margin 0 auto margin-top 80px width 80% @@ -41,166 +40,139 @@ .keyboard-outer scrollable() - height: calc(100% - 200px); + height calc(100% - 200px) .fix-float float left position relative - left: 50% + left 50% .keyboard-table - float: left; + float left position relative - left: -50% + left -50% &.last - margin-left: 30px; - + margin-left 30px tbody:first-child tr:first-child th - padding-top: 0; - + padding-top 0 th - padding-top: 25px; - font-size: 16px; + padding-top 25px + font-size 16px font-family $AlternateFont font-weight bold - line-height: 1.5; - color: darken($Text1, 10%); - text-align: left; - + line-height 1.5 + color darken($Text1, 10%) + text-align left td - padding-top: 3px; - padding-bottom: 3px; - line-height: 22px; - + padding-top 3px + padding-bottom 3px + line-height 22px tr td:first-child - padding-top: 1px; - padding-right: 10px; - text-align: right; - white-space: nowrap; - + padding-top 1px + padding-right 10px + text-align right + white-space nowrap td span.mouse - width: 23px; - height: 19px; - margin-left: 1px; - margin-right: 6px; - vertical-align: bottom; + width 23px + height 19px + margin-left 1px + margin-right 6px + vertical-align bottom td span.key - margin-left: 7px; - margin-right: 7px; + margin-left 7px + margin-right 7px &:first-child - margin-left: 0; - + margin-left 0 &:last-child - margin-right: 0; - - + margin-right 0 .key - display: inline-block - color: lighten(#000, 10%) - font: bold 9pt arial - text-decoration: none - text-align: center - width: 23px - height: 21px - background: #eff0f2 - border-radius: 4px - border-top: 1px solid #f5f5f5 - box-shadow: - inset 0 0 25px #e8e8e8, - 0 1px 0 #c3c3c3, - 0 2px 0 #c9c9c9, - 0 2px 3px #333 - text-shadow: 0px 1px 0px #f5f5f5 - padding: 3px 0 0 - text-transform: uppercase - + display inline-block + color lighten(#000, 10%) + font bold 9pt arial + text-decoration none + text-align center + width 23px + height 21px + background #eff0f2 + border-radius 4px + border-top 1px solid #f5f5f5 + box-shadow inset 0 0 25px #e8e8e8, 0 1px 0 #c3c3c3, 0 2px 0 #c9c9c9, 0 2px 3px #333 + text-shadow 0px 1px 0px #f5f5f5 + padding 3px 0 0 + text-transform uppercase + &.tab - text-align: left; - padding: 23px 0 0 10px; - font-size: 7.5pt; - text-transform: lowercase; + text-align left + padding 23px 0 0 10px + font-size 7.5pt + text-transform lowercase - &.esc - padding: 6px 2px 0 0; - font-size: 7.5pt; - text-transform: lowercase; - + padding 6px 2px 0 0 + font-size 7.5pt + text-transform lowercase &.delete, &.tab - width: 36px; - + width 36px &.caps, &.enter - width: 54px; - + width 54px &.shiftleft, &.shiftright - width: 56px; - + width 56px &.fn, &.control, &.option, &.command, &.spacebar - height: 24px; - + height 24px &.control - width: 38px; + width 38px - &.option - width: 23px; + width 23px - &.command - width: 38px; + width 38px - &.spacebar - width: 113px; - + width 113px &.down - height: 11px; - + height 11px &.up, &.leftarrow, &.rightarrow - height: 12px; - + height 12px &.leftarrow, &.rightarrow - padding: 5px 5px 5px; - + padding 5px 5px 5px &.up - padding: 5px 5px 1px; - border-bottom-right-radius: 0px; - border-bottom-left-radius: 0px; - + padding 5px 5px 1px + border-bottom-right-radius 0px + border-bottom-left-radius 0px &.down - padding: 0 5px 5px; - border-top-left-radius: 0px; - border-top-right-radius: 0px; - + padding 0 5px 5px + border-top-left-radius 0px + border-top-right-radius 0px &.arrow - font-size: 14px; + font-size 14px diff --git a/src/app/styl/views/list.styl b/src/app/styl/views/list.styl new file mode 100644 index 0000000000..2b7c7b2637 --- /dev/null +++ b/src/app/styl/views/list.styl @@ -0,0 +1,109 @@ +.list + height 100% + width calc(100% - 5px) + fixed top left + text-align center + scrollable() + + &::-webkit-scrollbar-track + margin-top $HeaderHeight + margin-bottom 5px + + .items_show + padding-top $HeaderHeight + -webkit-user-select none + text-align left + display flex + flex-direction row + flex-wrap wrap + justify-content space-between + align-content flex-start + align-items flex-start + width calc(50% - 5px) + height 100% + float left + background rgba(138, 138, 138, 0.14) + scrollable() + + &::-webkit-scrollbar-track + margin-top $HeaderHeight + + .title_history + color $Text1 + padding 25px 10px 10px + font-size 1.2em + text-align left + + .items + padding-top 0 + + .items_movie + padding-top $HeaderHeight + -webkit-user-select none + text-align left + display flex + flex-direction row + flex-wrap wrap + justify-content space-between + align-content flex-start + align-items flex-start + width calc(50% - 5px) + height 100% + float left + scrollable() + + &::-webkit-scrollbar-track + margin-top $HeaderHeight + + .title_history + color $Text1 + padding 25px 10px 10px + font-size 1.2em + text-align left + + .items + padding-top 0 + .items + padding-top $HeaderHeight + -webkit-user-select none + text-align left + display flex + flex-direction row + flex-wrap wrap + justify-content space-between + align-content flex-start + align-items flex-start + width calc(100% - 5px) + will-change transform, scroll-position + + .error + font-size 1.5em + text-align center + margin-top 180px + width 80% + margin-left 10% + position absolute + color $TextError + font-weight bold + + > .spinner + position fixed + width 100% + height 100% + background rgba(0, 0, 0, 0.5) center center no-repeat + pointer-events all + z-index 1 + + .loading-container + margin 50vh auto 0px + opacity .8 +.default-frame + .list + &::-webkit-scrollbar-track + margin-top $FilterBarHeight + .items_show + &::-webkit-scrollbar-track + margin-top $FilterBarHeight + .items_movie + &::-webkit-scrollbar-track + margin-top $FilterBarHeight diff --git a/src/app/styl/views/loading.styl b/src/app/styl/views/loading.styl index 1acc7b6e67..dd3bad82e2 100644 --- a/src/app/styl/views/loading.styl +++ b/src/app/styl/views/loading.styl @@ -1,8 +1,8 @@ .loading - position: absolute - z-index: 9 - background-color: $BgColor1 - -webkit-user-select: none + position absolute + z-index 9 + background-color $BgColor1 + -webkit-user-select none width 100% height 100% opacity 1 @@ -14,55 +14,56 @@ -webkit-backface-visibility hidden .minimize-icon - top: 47px - right: 20px - position: fixed - color: $CloseButton - font-size: 18px - cursor: pointer - z-index: 100 - -webkit-font-smoothing: antialiased - transition: color 0.2s + top 47px + right 20px + position fixed + color $CloseButton + font-size 18px + cursor pointer + z-index 100 + -webkit-font-smoothing antialiased + transition color 0.2s &:hover - color: $CloseButtonHover + color $CloseButtonHover .maximize-icon - display: none - bottom: 20px - right: 20px - position: fixed - color: $CloseButton - font-size: 25px - cursor: pointer - z-index: 100 - background: $BgColor2 - padding: 10px 20px - opacity: 0.9 - border-radius: 3px - box-shadow: 0 2px 6px 0 rgba(0,0,0,0.15), 0 4px 14px 0 rgba(0,0,0,0.25) - -webkit-font-smoothing: antialiased - transition: background 0.2s, color 0.2s, opacity 0.2s + display none + bottom 20px + right 20px + position fixed + color $CloseButton + font-size 25px + cursor pointer + z-index 100 + background $BgColor2 + padding 10px 20px + opacity 0.9 + border-radius 3px + box-shadow 0 2px 6px 0 rgba(0,0,0,0.15), 0 4px 14px 0 rgba(0,0,0,0.25) + -webkit-font-smoothing antialiased + transition background 0.2s, color 0.2s, opacity 0.2s &:hover - color: $ButtonText - background: $ButtonBgHover - opacity: 1 + color $ButtonText + background $ButtonBgHover + opacity 1 &.done:hover - background: #27ae60 + color #fff + background #27ae60 & > * - font-size: 12px - vertical-align: top - line-height: 25px + font-size 12px + vertical-align top + line-height 25px #maxic - font-size: 18px - margin-left: 10px + font-size 18px + margin-left 10px #userISP - text-decoration: underline + text-decoration underline .vpn margin-top 20px @@ -72,14 +73,14 @@ margin-top 20px .loading-backdrop - position: absolute - width: 100% - height: 100% + position absolute + width 100% + height 100% background-repeat no-repeat background-position-x 50% background-position-y 50% background-size cover - -webkit-filter: blur(20px) brightness(0.7) + -webkit-filter blur(20px) brightness(0.7) .loading-backdrop-overlay width 100% @@ -89,10 +90,10 @@ background-color #000 .state-flex - height: 100% - display: flex - align-items: center - justify-content: center + height 100% + display flex + align-items center + justify-content center .state color #fff @@ -115,7 +116,7 @@ .external-play font-size 14px - font-style: italic + font-style italic padding-bottom 6px visibility hidden @@ -147,7 +148,6 @@ background-color #bababa border-radius 13px display none - //padding 3px & > div background-color $ButtonBgActive @@ -176,46 +176,46 @@ margin-left 5px #cancel-button-regular - margin-top: 10px - font-size: 10px - cursor: pointer + margin-top 10px + font-size 10px + cursor pointer display inline-block margin-right 5px .vpn .heading - font-size: 25px - margin-bottom: 10px + font-size 25px + margin-bottom 10px .subheading - font-size: 15px - margin-bottom: 10px - line-height: 20px + font-size 15px + margin-bottom 10px + line-height 20px .flex-map - display: flex - align-items: center - margin-top: 20px - margin-bottom: 20px + display flex + align-items center + margin-top 20px + margin-bottom 20px .details - padding-left: 20px + padding-left 20px .group - margin-bottom: 15px; - display: flex - text-align: left; + margin-bottom 15px + display flex + text-align left .fixed-width - width: 140px - + width 140px .map - width: 300px + width 300px img - border: 10px solid #bbb; - width: 100% + border 10px solid #bbb + width 100% .cancel-button z-index 2 cursor pointer width 120px height 35px + line-height 1 margin 20px auto auto auto -moz-border-radius 3px -webkit-border-radius 3px @@ -228,17 +228,16 @@ transition background-color .5s &:hover - background: $ButtonBgHover - text-decoration: none + background $ButtonBgHover + text-decoration none &:active - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + background $ButtonBgActive .cancel-button-text -webkit-backface-visibility hidden position relative - color #fff font-family $MainFont, $Font, $AlternateFont -webkit-font-smoothing antialiased text-align center @@ -276,7 +275,7 @@ border-radius 4px left 0 right 0 - background: rgba(0, 0, 0, .6) + background rgba(0, 0, 0, .6) display inline-block &:hover @@ -362,12 +361,12 @@ content '\f071' color #FFFF00 font-family "Font Awesome 6 Free" - font-weight: 900 + font-weight 900 font-size 16px padding-right 8px @keyframes bounce_bar 0% - margin-left:-100%; + margin-left:-100% 100% - margin-left:100%; + margin-left:100% diff --git a/src/app/styl/views/main_window.styl b/src/app/styl/views/main_window.styl index 508b53bd32..f959b592c8 100644 --- a/src/app/styl/views/main_window.styl +++ b/src/app/styl/views/main_window.styl @@ -48,46 +48,46 @@ body, display none &.right - top: 4px - right: 0px - width: 4px - height: 100% + top 4px + right 0px + width 4px + height 100% &.left - bottom: 4px - left: 0px - width: 4px - height: 100% + bottom 4px + left 0px + width 4px + height 100% &.bottom bottom 0px right 4px width 100% height 4px &.top - top: 0px - left: 4px - width: 100% - height: 4px + top 0px + left 4px + width 100% + height 4px #drop-mask - position: absolute - width: 100% - height: 100% - z-index: 999 - display: none + position absolute + width 100% + height 100% + z-index 999 + display none -webkit-filter blur(5px) filter blur(5px) .close-icon - top: 45px - right: 20px - position: fixed - color: $CloseButton - font-size: 25px - line-height: 25px + top 45px + right 20px + position fixed + color $CloseButton + font-size 25px + line-height 25px cursor pointer z-index 100 transition all .5s - font-smoothing: antialiased + font-smoothing antialiased &:hover color $CloseButtonHover @@ -95,11 +95,11 @@ body, .movie-detail, .shows-container-contain .close-icon - top: 75px; + top 75px .knm - transition: all 3000ms ease-in-out; - transform:rotate(180deg); + transition all 3000ms ease-in-out + transform rotate(180deg) .dragzone width 86% @@ -108,15 +108,15 @@ body, .notification_alert position fixed - pointer-events: none - background-color rgba($NotifAlertBg,.8); + pointer-events none + background-color rgba($NotifAlertBg,.8) border-radius 4px padding 10px top 78px right 20px color $NotifAlertText - font-family $AlternateFont - font-size 14px + font-family $MainFont, $AlternateFont + font-size 13px z-index 999 display none diff --git a/src/app/styl/views/misc.styl b/src/app/styl/views/misc.styl index 1ef37b7c5a..2c84cf9648 100644 --- a/src/app/styl/views/misc.styl +++ b/src/app/styl/views/misc.styl @@ -1,50 +1,49 @@ fadeicon(image, posx, posx2, size) - width: size - height: size - position: relative; + width size + height size + position relative &:before - content: "" - position: absolute - top: 0; left: 0; bottom: 0; right: 0 - width: size - height: size - background-image: url(../images/icons/image.png) - background-position: posx 0px - background-repeat: no-repeat - opacity: 1 - -webkit-transition: opacity 0.5s + content "" + position absolute + top 0 + left 0 + bottom 0 + right 0 + width size + height size + background-image url(../images/icons/image.png) + background-position posx 0px + background-repeat no-repeat + opacity 1 + -webkit-transition opacity 0.5s &:after - content: "" - position: absolute - top: 0; left: 0; bottom: 0; right: 0 - width: size - height: size - background-image: url(../images/icons/image.png) - background-position: posx2 0px - background-repeat: no-repeat - opacity: 0 - -webkit-transition: opacity 0.5s + content "" + position absolute + top 0 + left 0 + bottom 0 + right 0 + width size + height size + background-image url(../images/icons/image.png) + background-position posx2 0px + background-repeat no-repeat + opacity 0 + -webkit-transition opacity 0.5s &:hover:before - opacity: 0; + opacity 0 &:hover:after - opacity: 1; - - - + opacity 1 .left - float: left + float left .right float right - // Gives nicer scrollbars to an element scrollable() overflow-x hidden - // Overflow: overlay is an undocumented webkit feature. It places the scrollbar *on top* of the content instead of eating some 16px. - // It's buggy, though (it paints the scrollbar *over* the content and composites badly, so it will crop the content anyway ) overflow-y overlay - // Inertial scrolling for touch devices (mostly useless here) -webkit-overflow-scrolling touch &::-webkit-scrollbar @@ -59,7 +58,7 @@ scrollable() border-radius 2px &:hover - background-color: $ScrollBarThumbHover + background-color $ScrollBarThumbHover &::-webkit-resizer, &::-webkit-scrollbar-corner, @@ -67,7 +66,6 @@ scrollable() &::-webkit-scrollbar-track-piece display none - .tooltip-arrow position absolute width 0 @@ -138,13 +136,16 @@ scrollable() transition all 0.5s .tooltip-inner - max-width 200px - padding 3px 8px + max-width 280px + padding 4px 8px color #fff text-align center text-decoration none background-color rgba(9, 13, 18, 0.75) border-radius 4px + font-family $MainFont !important + font-size 12px !important + line-height 18px !important .toolcimg max-width 102px diff --git a/src/app/styl/views/movie_detail.styl b/src/app/styl/views/movie_detail.styl index 4917e7412b..1e8c697ee2 100644 --- a/src/app/styl/views/movie_detail.styl +++ b/src/app/styl/views/movie_detail.styl @@ -1,90 +1,106 @@ .movie-detail - display: flex - flex-direction: row - justify-content: flex-start - flex-flow: row wrap - height: 100vh //needs to become calc(100vh - 65px) - padding-top: 65px //when webkit calc() is fixed = m34 - width: 100vw - user-select: none - backface-visibility: hidden - background-color: $BgColor1 - position: fixed + display flex + flex-direction row + justify-content flex-start + flex-flow row wrap + height 100vh + padding-top 65px + width 100vw + user-select none + backface-visibility hidden + background-color $BgColor1 + position fixed + + .spinner + position fixed + width 100% + height 100% + background rgba(0, 0, 0, 0.5) center center no-repeat + pointer-events all + z-index 10 + display none + top 0 + + .loading-container + margin 50vh auto 0px + opacity .8 + .backdrop-overlay - width: 100vw - height: 100vh - position: absolute - opacity: 0.65 - background-color: #000 + width 100vw + height 100vh + position absolute + opacity 0.65 + background-color #000 .backdrop - width: 100vw - height: calc(100% - 67px) - position: absolute - opacity: 0 + width 100vw + height 100% + margin-top -35px + position absolute + opacity 0 background-position-x 50% background-position-y 50% - -webkit-filter: blur(20px) brightness(0.7) - background-repeat: no-repeat - background-size: cover + -webkit-filter blur(20px) brightness(0.7) + background-repeat no-repeat + background-size cover &.fadein - transition: opacity .3s ease-in; - opacity: 1 + transition opacity .3s ease-in + opacity 1 .poster-box - height: 75vh - margin-top: 8vh - width: 35vw - padding-left: 4vw + height 75vh + margin-top 8vh + width 35vw + padding-left 4vw .mcover-image - float: right - width: 100% - height: 100% - max-width: 50vh - max-height: 75vh - position: relative - margin-right: 1vw - border-radius: 4px + float right + width 100% + height 100% + max-width 50vh + max-height 75vh + position relative + margin-right 1vw + border-radius 4px opacity 0 - backface-visibility: hidden + backface-visibility hidden &.fadein - transition: opacity .3s ease-in; - opacity: 1 + transition opacity .3s ease-in + opacity 1 .content-box - height: 75vh - margin-top: 8vh - width: 64.99vw - padding-right: 4vw - display: flex - justify-content: space-between - flex-direction: column + height 75vh + margin-top 8vh + width 64.99vw + padding-right 4vw + display flex + justify-content space-between + flex-direction column .meta-container - height: calc(100% - 70px) - flex: 2 - overflow: hidden - padding-top: 10px - margin-top: -10px + height calc(100% - 70px) + flex 2 + overflow hidden + padding-top 10px + margin-top -10px .title - color: #FFF - position: relative - top: -4px - text-stroke: 1px rgba(0,0,0,0.1) - font-size: 38px - font-family: $MainFont - font-smoothing: antialiased + color #FFF + position relative + top -4px + text-stroke 1px rgba(0,0,0,0.1) + font-size 38px + font-family $MainFont + font-smoothing antialiased .metadatas - top: 15px - height: 20px - position: relative - display: flex - flex-wrap: wrap + top 15px + height 20px + position relative + display flex + flex-wrap wrap .metaitem, .year, .certification, .show-cast, .movie-imdb-link &:hover ~ .tmdb-link @@ -92,125 +108,124 @@ transition-delay .8s .metaitem - color: #f8f8f8 - font-size: 12px - position: relative - font-family: $MainFontBold - text-stroke: 1px rgba(0,0,0,0.1) - font-smoothing: antialiased - max-width: 29% - overflow: hidden - white-space: nowrap - text-overflow: ellipsis + color #f8f8f8 + font-size 12px + position relative + font-family $MainFontBold + text-stroke 1px rgba(0,0,0,0.1) + font-smoothing antialiased + max-width 29% + overflow hidden + white-space nowrap + text-overflow ellipsis &::before - content: "" - margin: 4px 15px 0px 15px - position: relative - display: inline-block - width: 4px - float: left - height: 4px - border-radius: 2px - background-color: #dbdbdd + content "" + margin 4px 15px 0px 15px + position relative + display inline-block + width 4px + float left + height 4px + border-radius 2px + background-color #dbdbdd &:first-child::before - display: none + display none .show-cast - color: #f8f8f8 - font-size: 12px - position: relative - font-family: "Font Awesome 6 Free" - text-stroke: 1px rgba(0,0,0,0.1) - font-smoothing: antialiased - cursor: pointer + color #f8f8f8 + font-size 12px + position relative + font-family "Font Awesome 6 Free" + text-stroke 1px rgba(0,0,0,0.1) + font-smoothing antialiased + cursor pointer .tmdb-link - padding-left: 12px + padding-left 12px padding-right 6px - color: #f8f8f8 - font-size: 11px - position: relative - font-family: "Font Awesome 6 Free" - text-stroke: 1px rgba(0,0,0,0.1) - font-smoothing: antialiased - cursor: pointer - opacity: 0 - transition: opacity .3s ease-in - transition-delay: .2s + color #f8f8f8 + font-size 11px + position relative + font-family "Font Awesome 6 Free" + text-stroke 1px rgba(0,0,0,0.1) + font-smoothing antialiased + cursor pointer + opacity 0 + transition opacity .3s ease-in + transition-delay .2s &:hover - opacity: 1 - transition-delay: 0s + opacity 1 + transition-delay 0s &.disabled &:hover - cursor: default - opacity: 0.4 + cursor default + opacity 0.4 .year, .certification - color: #f8f8f8 - font-size: 12px - position: relative - font-family: $MainFontBold - text-stroke: 1px rgba(0,0,0,0.1) - font-smoothing: antialiased - cursor: pointer + color #f8f8f8 + font-size 12px + position relative + font-family $MainFontBold + text-stroke 1px rgba(0,0,0,0.1) + font-smoothing antialiased + cursor pointer .movie-imdb-link - margin-top: -3px - padding-top: 3px - width: 29px - height: 16px - position: relative - cursor: pointer - background: url(../images/icons/imdb.png) right top no-repeat - + margin-top -3px + padding-top 3px + width 29px + height 16px + position relative + cursor pointer + background url(../images/icons/imdb.png) right top no-repeat .rating-container .hidden - display: none + display none .number-container - width: auto - float: left - font-size: 12px - font-family: $MainFontBold - color: #FFF - cursor: pointer - z-index: 2 + width auto + float left + font-size 12px + font-family $MainFontBold + color #FFF + cursor pointer + z-index 2 em - font-size: 0.8em + font-size 0.8em .star-container - width: auto - float: left - position: relative - z-index: 2 - cursor: pointer + width auto + float left + position relative + z-index 2 + cursor pointer .rating-star color #ffc900 font-size 11px - padding-right: 3px + padding-right 3px .rating-star-half color #ffc900 font-size 11px margin-left -4px - padding-right: 3px + padding-right 3px .rating-star-half-empty color #a3a5a7 font-size 11px - margin-left: -4px + margin-left -4px .rating-star-empty color #a3a5a7 font-size 11px - padding-right: 3px + padding-right 3px .rating-star-half-container width 1em @@ -221,469 +236,468 @@ margin-left 4px .status-indicators - margin-left: auto - display: flex - flex-direction: row-reverse - margin-right: 2% + margin-left auto + display flex + flex-direction row-reverse + margin-right 2% &>*:not(:first-child) - margin-right: 1em + margin-right 1em + border-radius 50% .health-icon - position: relative - font-size: 14px - color: #737577 - cursor: pointer - margin-top: -1px + position relative + font-size 14px + color #737577 + cursor pointer + margin-top -1px + border-radius 50% &.Bad - color: #d53f3f + color #d53f3f &.Medium - color: #ece523 + color #ece523 &.Good - color: #a3e147 + color #a3e147 &.Excellent - color: #2ad942 + color #2ad942 .magnet-link - position: relative - top: 2px - font-size: 13px - color: #DDD - cursor: pointer - margin-top: -2px - margin-right: 12px + position relative + top 2px + font-size 13px + color #DDD + cursor pointer + margin-top -2px + margin-right 12px &:hover - color: #FFF - transition: all .5s + color #FFF + transition all .5s .source-link - position: relative - font-size: 13px - color: #DDD - cursor: pointer - margin-top: -2px - margin-right: 10px + position relative + font-size 13px + color #DDD + cursor pointer + margin-top -2px + margin-right 10px &:hover - color: #FFF - transition: all .5s + color #FFF + transition all .5s img - height: 16px + height 16px .overview - position: relative - max-height: 35% - overflow: hidden - float: none - color: #FFF - top: 25px - padding-right: 2% - font-family: $MainFont - font-smoothing: antialiased - font-size: 13px - line-height: 22px - text-align: justify - text-stroke: 1px rgba(0,0,0,0.1) - backface-visibility: hidden - scrollable(); + position relative + max-height 35% + overflow hidden + float none + color #FFF + top 25px + padding-right 2% + font-family $MainFont + font-smoothing antialiased + font-size 13px + line-height 22px + text-align justify + text-stroke 1px rgba(0,0,0,0.1) + backface-visibility hidden + scrollable() span - opacity: 0.7 - font-size: 90% + opacity 0.7 + font-size 90% span.cname - cursor: pointer - opacity: 1 - font-size: 100% + cursor pointer + opacity 1 + font-size 100% span.showall-cast - cursor: pointer - opacity: 1 - font-size: 100% + cursor pointer + opacity 1 + font-size 100% p.sline - line-height: 0.6 + line-height 0.6 #torrent-list - position: relative - top: 48px - max-height: 55% - margin: 0 20px 0 3px + position relative + top 48px + max-height 55% + margin 0 20px 0 3px table tr &:hover - background: rgba(255,255,255,0.1) + background rgba(255,255,255,0.1) td - color: #c3c5c7 - background: none + color #c3c5c7 + background none &:nth-child(5) - padding-right: 20px + padding-right 20px td.provider - width: 36px - padding-left: 10px + width 36px + padding-left 10px td.action - width: 36px - padding-left: 1px + width 36px + padding-left 1px &:hover - color: #fff - transition: all .5s + color #fff + transition all .5s .play-control - display: flex - flex-direction: row - justify-content: space-between - white-space: nowrap - height: 70px - line-height: 35px - margin: 8px 25px 1px 16px + display flex + flex-direction row + justify-content space-between + white-space nowrap + height 70px + line-height 35px + margin 8px 25px 1px 16px .flex-left - min-width: 420px - margin-right: -15px + min-width 420px + margin-right -15px .setup-container - display: flex - flex-direction: row - justify-content: space-between - margin-left: -10px + display flex + flex-direction row + justify-content space-between + margin-left -10px .toggles-container - display: flex - flex: 2 - padding-bottom: 10px + display flex + flex 2 + padding-bottom 10px .favourites-toggle - cursor: pointer - padding: 5px - padding-left: 24px - float: left - color: #FFF - height: 26px - position: relative - width: auto - font-family: $MainFont - font-smoothing: antialiased - font-size: 12px - line-height: 17px - margin-right: 20px + cursor pointer + padding 5px + padding-left 24px + float left + color #FFF + height 26px + position relative + width auto + font-family $MainFont + font-smoothing antialiased + font-size 12px + line-height 17px + margin-right 20px &:before - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: #FFF - left: 0 - opacity: 1 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color #FFF + left 0 + opacity 1 + transition opacity 0.5s &:after - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: $ButtonBgActive - left: 0 - opacity: 0 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color $ButtonBgActive + left 0 + opacity 0 + transition opacity 0.5s &:hover &:before - opacity: 0 + opacity 0 &:after - opacity: 1 - + opacity 1 &.selected - height: 18px - position: relative + height 18px + position relative &:before - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: $FavoriteColor - left: 0 - opacity: 1 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color $FavoriteColor + left 0 + opacity 1 + transition opacity 0.5s &:after - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: #FFF - left: 0 - opacity: 0 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color #FFF + left 0 + opacity 0 + transition opacity 0.5s &:hover &:before - opacity: 0 + opacity 0 &:after - opacity: 1 + opacity 1 .watched-toggle - cursor: pointer - padding: 5px - padding-left: 28px - float: left - color: #FFF - height: 26px - position: relative - width: auto - font-family: $MainFont - font-smoothing: antialiased - font-size: 12px - line-height: 17px + cursor pointer + padding 5px + padding-left 28px + float left + color #FFF + height 26px + position relative + width auto + font-family $MainFont + font-smoothing antialiased + font-size 12px + line-height 17px &:before - content: "\f070" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: #FFF - left: 0 - opacity: 1 - transform: scaleY(0.9) - transition: opacity 0.5s + content "\f070" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color #FFF + left 0 + opacity 1 + transform scaleY(0.9) + transition opacity 0.5s &:after - content: "\f00c" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 20px - color: #299000 - left: 0 - opacity: 0 - transition: opacity 0.5s + content "\f00c" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 20px + color #299000 + left 0 + opacity 0 + transition opacity 0.5s &:hover &:before - opacity: 0 + opacity 0 &:after - opacity: 1 - + opacity 1 &.selected &:before - content: "\f00c" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 20px - color: #299000 - left: 0 - opacity: 1 - transition: opacity 0.5s + content "\f00c" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 20px + color #299000 + left 0 + opacity 1 + transition opacity 0.5s &:after - content: "\f070" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: #FFF - left: 0 - opacity: 0 - transition: opacity 0.5s + content "\f070" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color #FFF + left 0 + opacity 0 + transition opacity 0.5s &:hover &:before - opacity: 0 + opacity 0 &:after - opacity: 1 + opacity 1 .show-all-torrents - position: relative - float: left - font-family: $MainFont - -webkit-font-smoothing: antialiased - font-size: 11px - color: #fff - transition: all .2s ease-in, margin 0s - padding: 0 6px - margin: 6px 6px 0 -2px - border-radius: 10px - height: 23px - line-height: 23px - cursor: pointer + position relative + float left + font-family $MainFont + -webkit-font-smoothing antialiased + font-size 11px + color #fff + transition all .2s ease-in, margin 0s + padding 0 6px + margin 6px 6px 0 -2px + border-radius 10px + height 23px + line-height 23px + cursor pointer &:hover, &.active - color: $QualitySelectorText - background: $QualitySelectorBg + color $QualitySelectorText + background $QualitySelectorBg &.fa-spinner - font-family: "Font Awesome 6 Free" - transition: none - margin-left: 6px + font-family "Font Awesome 6 Free" + transition none + margin-left 6px + color #fff &:hover, &.active - background: none + background none .play-selector - position: relative - float: left + position relative + float left .startStreaming - margin-left: 12px - margin-right: 12px + margin-left 12px + margin-right 12px &:after - content: '' - width: 70% - height: 100% - top: 0 - left: 0 - position: absolute + content '' + width 70% + height 100% + top 0 + left 0 + position absolute .quality-selector - position: relative - float: left + position relative + float left .sdow-quality - line-height: normal; - padding: 4px; - height 35px; + line-height normal + padding 4px + height 35px div - cursor: pointer - float: left - font-family: $MainFont; - -webkit-font-smoothing: antialiased; - font-size: 11px - color: #fff - transition: all .2s ease-in - padding: 4px - margin-right: 6px - margin-top: 2px + cursor pointer + float left + font-family $MainFont + -webkit-font-smoothing antialiased + font-size 11px + color #fff + transition all .2s ease-in + padding 4px + margin-right 6px + margin-top 2px .disabled - opacity: .3 - cursor: default + opacity .3 + cursor default .active - cursor: pointer - opacity: 1 - color: $QualitySelectorText - background: $QualitySelectorBg - border-radius: 10px - font-family: $MainFontBold - + cursor pointer + opacity 1 + color $QualitySelectorText + background $QualitySelectorBg + border-radius 10px + font-family $MainFontBold .movie-quality-container - margin-top: 10px - float: left - position: relative - height: 15px - width: 95px - left: 3% - line-height: 1 + margin-top 10px + float left + position relative + height 15px + width 95px + left 3% + line-height 1 .sdow-quality div - cursor: pointer - float: left - font-family: $MainFont; - font-smoothing: antialiased - font-size: 11px - color: $ShowText1 - transition: all .2s ease-in - padding: 4px + cursor pointer + float left + font-family $MainFont + font-smoothing antialiased + font-size 11px + color $ShowText1 + transition all .2s ease-in + padding 4px .tooltip - width: 85px + width 85px .disabled - opacity: .3 - cursor: default + opacity .3 + cursor default .active - cursor: pointer - opacity: 1 - color: $QualitySelectorText - background: $QualitySelectorBg - border-radius: 10px - font-family: $MainFontBold + cursor pointer + opacity 1 + color $QualitySelectorText + background $QualitySelectorBg + border-radius 10px + font-family $MainFontBold .switch - background: transparent - border-radius: 32px - display: block - height: 12px - position: absolute - left: 28px - width: 25px - border: 2px solid #fff - cursor: pointer + background transparent + border-radius 32px + display block + height 12px + position absolute + left 28px + width 25px + border 2px solid #fff + cursor pointer label - transition: color 0.2s ease - width: 20px - cursor: pointer + transition color 0.2s ease + width 20px + cursor pointer &:nth-of-type(1) - left: -38px - position: absolute - text-align: right + left -38px + position absolute + text-align right &:nth-of-type(2) - position: absolute - right: -30px - text-align: left + position absolute + right -30px + text-align left .tooltip - width: 130px + width 130px input - height: 7px - left: -27px - opacity: 0 - position: absolute - top: -4px - width: 79px - z-index: 2 - cursor: pointer + height 7px + left -27px + opacity 0 + position absolute + top -4px + width 79px + z-index 2 + cursor pointer &:checked - z-index: 0 + z-index 0 & ~ label &:nth-of-type(1) - color: $ButtonBgActive + color $ButtonBgActive &:nth-of-type(2) - color: #fff + color #fff & ~ .toggle - left: 0px - + left 0px & ~ :checked & ~ label &:nth-of-type(1) - color: #fff + color #fff &:nth-of-type(2) - color: $ButtonBgActive + color $ButtonBgActive & ~ .toggle - left: 11px + left 11px .toggle - transition: left 0.2s ease - background: $ButtonBgActive - border-radius: 50% - height: 10px - left: -0px - position: absolute - top: -1px - width: 10px + transition left 0.2s ease + background $ButtonBgActive + border-radius 50% + height 10px + left -0px + position absolute + top -1px + width 10px diff --git a/src/app/styl/views/movie_error.styl b/src/app/styl/views/movie_error.styl index 26bae53805..5e9698cb40 100644 --- a/src/app/styl/views/movie_error.styl +++ b/src/app/styl/views/movie_error.styl @@ -1,58 +1,58 @@ #movie-error .button - position: absolute - cursor: pointer - height: 35px - width: 250px - top: 0 - margin-top: 275px - border-radius: $ButtonRadius - background-clip: padding-box - background-color: $ButtonBg - padding: 0 15px - transition: background-color 0.5s - color: $ButtonText - font-family: $MainFont - font-smoothing: antialiased - text-align: center - font-size: 12px - line-height: 34px + position absolute + cursor pointer + height 35px + width 250px + top 0 + margin-top 275px + border-radius $ButtonRadius + background-clip padding-box + background-color $ButtonBg + padding 0 15px + transition background-color 0.5s + color $ButtonText + font-family $MainFont + font-smoothing antialiased + text-align center + font-size 12px + line-height 34px &:hover - background: $ButtonBgHover - text-decoration: none + background $ButtonBgHover + text-decoration none &:active - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + background $ButtonBgActive .button-text - margin-left: 12px - margin-right: 12px + margin-left 12px + margin-right 12px &:after - content: '' - width: 70% - height: 100% - top: 0 - left: 0 - position: absolute + content '' + width 70% + height 100% + top 0 + left 0 + position absolute i - font-size: 14px + font-size 14px .retry-button - visibility: hidden - position: relative - display: inline-block + visibility hidden + position relative + display inline-block .change-api, .online-search - visibility: hidden - width: auto - min-width: 250px - max-width: 300px - text-overflow: ellipsis - white-space: nowrap - position: relative - display: inline-block + visibility hidden + width auto + min-width 250px + max-width 300px + text-overflow ellipsis + white-space nowrap + position relative + display inline-block diff --git a/src/app/styl/views/notification.styl b/src/app/styl/views/notification.styl index dfb5c89412..26eac44377 100644 --- a/src/app/styl/views/notification.styl +++ b/src/app/styl/views/notification.styl @@ -13,7 +13,7 @@ font-weight bold text-align center line-height 27px - padding 9px 15px + padding 11px 15px color $NotificationText border 1px solid rgba($NotificationBorderColor,.7) transition all .5s @@ -41,8 +41,8 @@ .close position absolute - top 5px - right 7px + top 6px + right 8px opacity 0.7 color white &:hover @@ -66,8 +66,8 @@ opacity .6 &:active - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) background $NotificationBtn opacity .7 @@ -82,6 +82,6 @@ p font-weight 100 - line-height: 20px + line-height 20px diff --git a/src/app/styl/views/player.styl b/src/app/styl/views/player.styl index 5e1b05b6d8..99c5ef8e19 100644 --- a/src/app/styl/views/player.styl +++ b/src/app/styl/views/player.styl @@ -1,263 +1,250 @@ #player, -.player { - width: 100% - height: 100% -} - -#video_player { - position: fixed - width: 100% - height: 100% -} - -.player { - z-index: 10 - position: absolute - overflow: hidden - background-color: #000 - video { - width: 100% - height: 100% - } - .details-player { - right: 10px - position: absolute - top: 20px - z-index: 20 - } - .minimize-icon { - top: -1px - right: 55px - position: absolute - color: #fff - font-size: 1.8em - font-smoothing: antialiased - transition: all 0.5s - &:hover { - cursor: pointer - color: #a3a5a7 - } - } - .maximize-icon { - display: none - bottom: 20px - right: 20px - position: fixed - color: $CloseButton - font-size: 25px - cursor: pointer - z-index: 100 - background: $BgColor2 - padding: 10px 20px - opacity: 0.9 - border-radius: 3px - box-shadow: 0 2px 6px 0 rgba(0,0,0,0.15), 0 4px 14px 0 rgba(0,0,0,0.25) - font-smoothing: antialiased - transition: background 0.2s, color 0.2s, opacity 0.2s - &:hover { - color: $ButtonText - background: $ButtonBgHover - opacity: 1 - } - &.done:hover { - background: #27ae60 - } - & > * { - font-size: 12px - vertical-align: top - line-height: 25px - } - #maxic { - font-size: 18px - margin-left: 10px - } - } - .close-info-player { - top: -1px - right: 18px - position: absolute - color: #fff - font-size: 2em - font-smoothing: antialiased - transition: all 0.5s - &:hover { - cursor: pointer - color: #a3a5a7 - } - } - .quality-info-player { - position: absolute - right: 132px - top: 3px - font-size: 1.3em - color: #fff - font-weight: bold - } - .state-info-player { - position: absolute - right: 90px - top: 120px +.player + width 100% + height 100% + +#video_player + position fixed + width 100% + height 100% + display flex + align-items center + justify-content center + +.player + z-index 10 + position absolute + overflow hidden + background-color #000 + video + width 100% + height 100% + + .details-player + right 10px + position absolute + top 20px + z-index 20 + + .minimize-icon + top -1px + right 55px + position absolute + color #fff + font-size 1.8em + font-smoothing antialiased + transition all 0.5s + &:hover + cursor pointer + color #a3a5a7 + + .maximize-icon + display none + bottom 20px + right 20px + position fixed + color $CloseButton + font-size 25px + cursor pointer + z-index 100 + background $BgColor2 + padding 10px 20px + opacity 0.9 + border-radius 3px + box-shadow 0 2px 6px 0 rgba(0,0,0,0.15), 0 4px 14px 0 rgba(0,0,0,0.25) + font-smoothing antialiased + transition background 0.2s, color 0.2s, opacity 0.2s + &:hover + color $ButtonText + background $ButtonBgHover + opacity 1 + + &.done:hover + color #fff + background #27ae60 + + & > * + font-size 12px + vertical-align top + line-height 25px + + #maxic + font-size 18px + margin-left 10px + + .close-info-player + top -1px + right 18px + position absolute + color #fff + font-size 2em + font-smoothing antialiased + transition all 0.5s + &:hover + cursor pointer + color #a3a5a7 + + .quality-info-player + position absolute + right 132px + top 3px + font-size 1.3em + color #fff + font-weight bold + + .state-info-player + position absolute + right 90px + top 120px font-size 50px - color: rgba(255,255,255,.3) - z-index: 23 - display: none - transition: all .4s ease-out - } - .eye-info-player { - position: absolute - font-size: 2em - color: #fff - top: -1px - right: 92px - z-index: 4 - transform: scaleY(0.9) - transition: all 0.5s - &:hover { - cursor: pointer - color: #a3a5a7 - & + .details-info-player { - display: inline-block - } - } - } - .details-info-player { - display: none - width: auto - background: rgba(31,31,31,0.7) - padding: 12px 20px - top: 32px - position: absolute - right: 45px - border-radius: 5px - - span { + color rgba(255,255,255,.3) + z-index 23 + display none + transition all .4s ease-out + + .eye-info-player + position absolute + font-size 2em + color #fff + top -1px + right 92px + z-index 4 + transform scaleY(0.9) + transition all 0.5s + &:hover + cursor pointer + color #a3a5a7 + & + .details-info-player + display inline-block + + .details-info-player + display none + width auto + background rgba(31,31,31,0.7) + padding 12px 20px + top 32px + position absolute + right 45px + border-radius 5px + + span position relative color #fff font-family $AlternateFont -webkit-font-smoothing antialiased - display: inline-box + display inline-box font-size 14px line-height 16px - &.loading-info-text { + &.loading-info-text float left - } - &.value { + + &.value float right - } - &.remaining { - margin-top: 10px - display: block - text-align: center - } - } + + &.remaining + margin-top 10px + display block + text-align center #sstatel-container, - #dwnloading { - text-align: center - } + #dwnloading + text-align center - #sstatel { - font-size: 170% - } + #sstatel + font-size 170% - .downloaded_player { - width: 100% - } + .downloaded_player + width 100% .filename_player, - .stream_url_player { - text-align: right - white-space: nowrap - overflow: hidden - text-overflow: ellipsis - } - } - .arrow-up { - width: 0 - height: 0 - border-left: 6px solid rgba(0,0,0,0) - border-right: 6px solid rgba(0,0,0,0) - border-bottom: 6px solid rgba(31,31,31,0.7) - top: -6px - right: 15px - position: absolute - } - .playing_next { - color: #fff - z-index: 23 - bottom: 10vh !important - width: 450px; - height: 140px; - padding: 10px - font-size: 20px - left: 3vw !important - display: none - background-color: rgba(0, 0, 0, 0.54) !important - overflow: hidden + .stream_url_player + text-align right + white-space nowrap + overflow hidden + text-overflow ellipsis + + .arrow-up + width 0 + height 0 + border-left 6px solid rgba(0,0,0,0) + border-right 6px solid rgba(0,0,0,0) + border-bottom 6px solid rgba(31,31,31,0.7) + top -6px + right 15px + position absolute + + .playing_next + color #fff + z-index 23 + bottom 10vh !important + width 450px + height 140px + padding 10px + font-size 20px + left 3vw !important + display none + background-color rgba(0, 0, 0, 0.54) !important + overflow hidden - .pn_poster { - width: 90px; - height: 120px; - float: left; - - .playing_next_poster { - width: 80px; - } - } - .pn_epinfo { - width: 235px; - height: 80px; - float: left; - text-align: left; + .pn_poster + width 90px + height 120px + float left + + .playing_next_poster + width 80px + + .pn_epinfo + width 235px + height 80px + float left + text-align left - .playing_next_show { - font-size: 15px; - font-weight: bold; - line-height: 20px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .playing_next_episode { - font-size: 11px; - line-height: 14px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .playing_next_number { - font-size: 17px; - margin-top: 18px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } - .pn_counter { - width: 105px; - height: 80px; - float: left; - - .playing_next_countertext { - font-size: 11px; - text-align: center; - text-transform: uppercase; - } - - #nextCountdown { - color: rgb(0, 143, 255); - font-size: 38px; - text-align: center; - margin-top: 6px; - } - } - .pn_btns { - width: 340px; - height: 40px; - float: left; - - .auto-next-btn { + .playing_next_show + font-size 15px + font-weight bold + line-height 20px + overflow hidden + text-overflow ellipsis + white-space nowrap + + .playing_next_episode + font-size 11px + line-height 14px + overflow hidden + text-overflow ellipsis + white-space nowrap + + .playing_next_number + font-size 17px + margin-top 18px + overflow hidden + text-overflow ellipsis + white-space nowrap + + .pn_counter + width 105px + height 80px + float left + + .playing_next_countertext + font-size 11px + text-align center + text-transform uppercase + + #nextCountdown + color rgb(0, 143, 255) + font-size 38px + text-align center + margin-top 6px + + .pn_btns + width 340px + height 40px + float left + + .auto-next-btn position relative float left margin-top 3px @@ -272,88 +259,80 @@ font-size 12px cursor pointer transition background-color .5s - &:hover { + &:hover background-color $ButtonBgHover color $SettingsButtonTextHover text-decoration none - } - &:active{ - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive - } - } - - } - - } - .verify-metadata { - color: #fff - z-index: 23 - bottom: 10vh !important - width: 450px; - height: 140px; - padding: 10px - font-size: 20px - left: 3vw !important - display: none - background-color: rgba(0, 0, 0, 0.54) !important - overflow: hidden + + &:active + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + background $ButtonBgActive + + .verify-metadata + color #fff + z-index 23 + bottom 10vh !important + width 450px + height 140px + padding 10px + font-size 20px + left 3vw !important + display none + background-color rgba(0, 0, 0, 0.54) !important + overflow hidden - .vm_poster { - width: 90px; - height: 120px; - float: left; - - .verifmeta_poster { - width: 80px; - } - } - .vm_epinfo { - width: 235px; - height: 80px; - float: left; - text-align: left; + .vm_poster + width 90px + height 120px + float left + + .verifmeta_poster + width 80px + + .vm_epinfo + width 235px + height 80px + float left + text-align left - .verifmeta_show { - font-size: 15px; - font-weight: bold; - line-height: 20px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .verifmeta_episode { - font-size: 11px; - line-height: 14px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .verifmeta_number { - font-size: 17px; - margin-top: 18px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } - .vm_box { - width: 105px; - height: 80px; - float: left; - - .verifmeta_boxtext { - font-size: 11px; - text-align: center; - text-transform: uppercase; - } - } - .vm_btns { - width: 340px; - height: 40px; - float: left; - - .vm-btn { + .verifmeta_show + font-size 15px + font-weight bold + line-height 20px + overflow hidden + text-overflow ellipsis + white-space nowrap + + .verifmeta_episode + font-size 11px + line-height 14px + overflow hidden + text-overflow ellipsis + white-space nowrap + + .verifmeta_number + font-size 17px + margin-top 18px + overflow hidden + text-overflow ellipsis + white-space nowrap + + .vm_box + width 105px + height 80px + float left + + .verifmeta_boxtext + font-size 11px + text-align center + text-transform uppercase + + .vm_btns + width 340px + height 40px + float left + + .vm-btn position relative float left margin-top 3px @@ -368,183 +347,113 @@ font-size 12px cursor pointer transition background-color .5s - &:hover { + &:hover background-color $ButtonBgHover color $SettingsButtonTextHover text-decoration none - } - &:active{ - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive - } - } - - } - - } - -/* span { - font-weight: bold - color: rgb(0, 143, 255) - } - } - .auto-next-btn { - position relative - float right - margin 15px - padding 12px - - - border-radius $ButtonRadius - background-color $ButtonBg - text-align center - color $SettingsButtonText - font-family $ButtonFont, $AlternateFont - font-size 13px - cursor pointer - transition background-color .5s - &:hover { - background-color $ButtonBgHover - color $SettingsButtonTextHover - text-decoration none - } - &.disabled { - background-color $ButtonBgDisabled - &:hover{ - background-color $ButtonBgDisabled - } - &:active{ - background-color $ButtonBgDisabled - } - } - - &.green{ - background-color #27AE60 - } - &.red{ - background-color #F15153 - } - &:active{ - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive - } - }*/ -} - -.player-title { - position: absolute - top: 18px - left: 16px - color: #fff - font-family: 'Open Sans', sans-serif - font-size: 17px - max-width: 85% - z-index: 3 - overflow: hidden - white-space: nowrap - text-overflow: ellipsis - padding-bottom: 3px -} - -.dragzone { - -webkit-app-region: drag - position: fixed - display: none -} - -.vjs-quality-button { - color: #fff - right: 35px - top: 19px - font-size: 12px -} - -.vjs-subtitles-button { - top: 24px -} - -.vjs_smallersub_button { - &.vjs-control { - top: 24px - } -} - -.vjs_biggersub_button { - &.vjs-control { - top: 24px - } -} - -.player-header-background { - position: absolute - background: linear-gradient(rgba(0,0,0,0.7), transparent 95%, transparent) !important - width: 100% !important - height: 75px !important - z-index: 3 - top: 0 -} + + &:active + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + background $ButtonBgActive + +.player-title + position absolute + top 18px + left 16px + color #fff + font-family 'Open Sans', sans-serif + font-size 17px + max-width 85% + z-index 3 + overflow hidden + white-space nowrap + text-overflow ellipsis + padding-bottom 3px + +.dragzone + -webkit-app-region drag + position fixed + display none + +.vjs-quality-button + color #fff + right 35px + top 19px + font-size 12px + +.vjs-subtitles-button + top 24px + +.vjs_smallersub_button + &.vjs-control + top 24px + +.vjs_biggersub_button + &.vjs-control + top 24px + +.player-header-background + position absolute + background linear-gradient(rgba(0,0,0,0.7), transparent 95%, transparent) !important + width 100% !important + height 75px !important + z-index 3 + top 0 .vjs-overlay, -.vjs-overlay.vjs-overlay-top-left { - position: absolute - width: auto - font-size: 16px - background-color: rgba(0,0,0,0.24) - color: #fff - font-family: "Open Sans Semibold" - font-smoothing: antialiased - padding: 14px - border-radius: 3px - top: 80px - right: 30px - text-align: right - opacity: 0 -} - -.vjs-overlay { - &.vjs-overlay-top { - margin-left: -16.5% - left: 50% - } - &.vjs-overlay-top-right { - left: auto - right: 5px - } - &.vjs-overlay-left { - top: 50% - margin-top: -15px - } - &.vjs-overlay-right { - left: auto - right: 5px - top: 50% - margin-top: -15px - } - &.vjs-overlay-bottom { - margin-left: -16.5% - left: 50% - top: auto - bottom: 4.5em - } - &.vjs-overlay-bottom-left { - bottom: 4.5em - top: auto - left: 5px - } - &.vjs-overlay-bottom-right { - bottom: 4.5em - top: auto - left: auto - right: 5px - } -} - -.video-js { - &.vjs-fullscreen { - &.vjs-user-inactive { - .vjs-tech { - pointer-events: none - } - } - } -} +.vjs-overlay.vjs-overlay-top-left + position absolute + width auto + font-size 16px + background-color rgba(0,0,0,0.24) + color #fff + font-family "Open Sans Semibold" + font-smoothing antialiased + padding 14px + border-radius 3px + top 80px + right 30px + text-align right + opacity 0 + +.vjs-overlay + &.vjs-overlay-top + margin-left -16.5% + left 50% + + &.vjs-overlay-top-right + left auto + right 5px + + &.vjs-overlay-left + top 50% + margin-top -15px + + &.vjs-overlay-right + left auto + right 5px + top 50% + margin-top -15px + + &.vjs-overlay-bottom + margin-left -16.5% + left 50% + top auto + bottom 4.5em + + &.vjs-overlay-bottom-left + bottom 4.5em + top auto + left 5px + + &.vjs-overlay-bottom-right + bottom 4.5em + top auto + left auto + right 5px + +.video-js + &.vjs-fullscreen + &.vjs-user-inactive + .vjs-tech + pointer-events none diff --git a/src/app/styl/views/seedbox.styl b/src/app/styl/views/seedbox.styl index a16678c425..c71cf7c1dd 100644 --- a/src/app/styl/views/seedbox.styl +++ b/src/app/styl/views/seedbox.styl @@ -6,6 +6,20 @@ -webkit-user-select none opacity 1 + .spinner + position fixed + width 100% + height 100% + background rgba(0, 0, 0, 0.5) center center no-repeat + pointer-events all + z-index 10 + display none + top 0 + + .loading-container + margin 50vh auto 0px + opacity .8 + .margintop height 100px @@ -18,46 +32,53 @@ font-size 17px .seedbox-details - width: 100vw - z-index: 1 - height: 100% - display: flex - flex-direction: row - padding-left: 20px /* left-pad */ + width 100vw + z-index 1 + height 100% + display flex + flex-direction row + padding-left 20px .seedbox-types ul, .seedbox-torrents ul - height: calc(100vh - 167px) - /* direction: rtl */ - text-align: right + height calc(100vh - 167px) + text-align right scrollable() li - padding: 0px 15px - margin: 1px 0px 1px 1px - float: left - width: calc(100% - 7px) - cursor: pointer + padding 0px 17px 0px 0px + margin 1px 0px 1px 1px + float left + width calc(100% - 7px) + cursor pointer .watched padding 10px 0 - color: $ShowWatchedIcon_false + color $ShowWatchedIcon_false transition color .5s - font-size: 0.9em - font-family: $MainFont, "Font Awesome 6 Free" + font-size 0.9em + font-family $MainFont, "Font Awesome 6 Free" &.true - color: $ShowWatchedIcon_true + color $ShowWatchedIcon_true &.disabled - cursor: not-allowed - opacity: 0.2 + cursor not-allowed + opacity 0.2 &:hover - color: $ShowWatchedIcon_false !important + color $ShowWatchedIcon_false !important .watched:not(.fa-download):not(.fa-upload) &:hover - color: $ShowWatchedIcon_true + color $ShowWatchedIcon_true + + .pause-torrent + width 50px + padding 10px 20px + + .resume-torrent + width 50px + padding 10px 19px li:nth-child(odd) background-color $ShowBgColor2 @@ -81,74 +102,74 @@ border-width 16px 6px 17px 6px a - text-decoration: none - font-size: 15px - line-height: 34px - font-weight: normal - float: left - flex-direction: row - direction: ltr + text-decoration none + font-size 15px + line-height 34px + font-weight normal + float left + flex-direction row + direction ltr span - float: left - margin: 0px 17px 0px 5px + float left + margin 0px div - white-space: nowrap - border-left: 1px solid $ShowBgColor1 - padding-left: 30px - text-align: left - overflow: hidden - text-overflow: ellipsis + white-space nowrap + border-left 1px solid $ShowBgColor1 + padding-left 25px + text-align left + overflow hidden + text-overflow ellipsis .seedbox-types, .seedbox-torrents .seedbox-types-title, .seedbox-torrent-title - font-size: 24px - overflow: hidden - text-overflow: ellipsis - white-space: nowrap - margin-bottom: 15px - margin-top: 2px - color: $ShowText1 + font-size 24px + overflow hidden + text-overflow ellipsis + white-space nowrap + margin-bottom 15px + margin-top 2px + color $ShowText1 .seedbox-types - min-width: 165px - max-width: 165px - flex-shrink: 1 - flex-grow: 1 - padding: 10px + min-width 165px + max-width 165px + flex-shrink 1 + flex-grow 1 + padding 10px .seedbox-types-list ul a - color: $SaisonListText - font-family: $AlternateFont - white-space: nowrap + color $SaisonListText + font-family $AlternateFont + white-space nowrap .seedbox-torrents - flex-grow: 2 - padding: 10px - width: calc(65vw - 20px) + flex-grow 2 + padding 10px + width calc(65vw - 20px) .seedbox-torrent-list ul - white-space: nowrap + white-space nowrap .seedbox-torrent-list ul li a - color: $EpisodeListText - font-family: $MainFont - min-width: 70px - max-width: calc(100% - 265px) + color $EpisodeListText + font-family $MainFont + min-width 70px + max-width calc(100% - 265px) .seedbox-torrent-list ul li.active a - color: $EpisodeSelectorText + color $EpisodeSelectorText .seedbox-torrent-list ul li.active i - color: rgba($EpisodeSelectorText,.5) + color rgba($EpisodeSelectorText,.5) .seedbox-torrent-list ul li.active i:not(.fa-download):not(.fa-upload) &:hover - color: $EpisodeSelectorText + color $EpisodeSelectorText .seedbox-torrent-list ul li.error - background: $NotificationError + background $NotificationError .notorrents-info display block @@ -191,85 +212,86 @@ font-size 20px .seedbox-overview - background: $ShowBgColor2 - flex-grow: 1 - flex-shrink: 0 - width: 35vw - min-width: 350px - padding: 12px 18px - margin-top: 28px - display: none + background $ShowBgColor2 + flex-grow 1 + flex-shrink 0 + width 35vw + min-width 350px + padding 12px 18px + margin-top 28px + display none .seedbox-infos .seedbox-infos-title - overflow: hidden - white-space: nowrap - text-overflow: ellipsis - font-size: 24px - font-weight: bold - margin-top: 2px - margin-bottom: 7px - color: $ShowText1 - min-height: 24px + overflow hidden + white-space nowrap + text-overflow ellipsis + font-size 24px + font-weight bold + margin-top 2px + margin-bottom 7px + color $ShowText1 + min-height 24px .seedbox-infos-links - position: absolute - right: 30px - margin-top: -2px + position absolute + right 30px + margin-top -2px &>div - padding: 5px 2px - cursor: pointer - position: relative + padding 5px 2px + border-radius 50% + cursor pointer + position relative .health-icon - font-size: 14px - color: #737577 - transition: all .3s ease-in + font-size 14px + color #737577 + transition all .3s ease-in &.Bad - color: #d53f3f + color #d53f3f &.Medium - color: #ece523 + color #ece523 &.Good - color: #a3e147 + color #a3e147 &.Excellent - color: #2ad942 + color #2ad942 .magnet-icon - font-size: 13px - color: #DDD - margin-right: 2px + font-size 13px + color #DDD + margin-right 1px &:hover - color: #FFF - transition: all .5s + color #FFF + transition all .5s .seedbox-infos-aired - font-size: 14px - line-height: 18px - margin-bottom: 10px - color: $ShowText2 + font-size 14px + line-height 18px + margin-bottom 10px + color $ShowText2 .seedbox-infos-date - margin-left: 5px - overflow: hidden - white-space: nowrap - text-overflow: ellipsis + overflow hidden + white-space nowrap + text-overflow ellipsis i - margin-right: 5px - font-family: $MainFont, "Font Awesome 6 Free" + margin-right 8px + font-family $MainFont, "Font Awesome 6 Free" .seedbox-infos-synopsis - color: $ShowText1 - font-size: 13px - line-height: 18px - text-align: justify - margin-top: 14px - margin-left: -18px - padding: 4px 15px 5px 0 - height: calc(100vh - 338px) + color $ShowText1 + font-size 13px + line-height 18px + text-align justify + margin-top 14px + margin-left -18px + padding 4px 6px 5px 0 + margin-right 9px + height calc(100vh - 338px) scrollable() ul @@ -323,19 +345,23 @@ color rgba($FileSelectorText, 0.4) transition all 0.3s cursor pointer - left calc(100% + 7px) - top -18px + left calc(100% - 23px) + top -25px + padding 10px + border-radius 50% &:hover color $CloseButtonHover .item-play - left -8px + left -18px position relative color rgba($FileSelectorText, 0.4) transition all 0.3s cursor pointer - top -18px + top -25px + padding 10px + border-radius 50% &:hover color $CloseButtonHover @@ -353,7 +379,7 @@ .item-icon position relative font-family "Font Awesome 6 Free" - font-weight: 900 + font-weight 900 font-style normal font-size 15px height 15px @@ -364,9 +390,9 @@ margin-top -16px &.torrent-icon:before - content: '\f016' + content '\f016' &.magnet-icon:before - content: '\f076' + content '\f076' &.magnet-icon:hover cursor pointer @@ -374,7 +400,7 @@ .online-size position relative - color: $TextError + color $TextError font-style normal font-size .9em left calc(100% - 35px) @@ -384,181 +410,171 @@ width calc(100% - 50px) .seedbox-watch - height: 60px - padding: 10px 0 + height 60px + padding 10px 0 .sdow-quality - margin-top: 20px - float: left + margin-top 20px + float left div - cursor: pointer - float: left - font-family: $MainFont; - -webkit-font-smoothing: antialiased; - font-size: 11px - color: $ShowText1 - transition: all .2s ease-in - padding: 4px - margin-right: 6px + cursor pointer + float left + font-family $MainFont + -webkit-font-smoothing antialiased + font-size 11px + color $ShowText1 + transition all .2s ease-in + padding 4px + margin-right 6px .disabled - opacity: .3 - cursor: default + opacity .3 + cursor default .active - cursor: pointer - opacity: 1 - color: $QualitySelectorText - background: $QualitySelectorBg - border-radius: 10px - font-family: $MainFontBold + cursor pointer + opacity 1 + color $QualitySelectorText + background $QualitySelectorBg + border-radius 10px + font-family $MainFontBold .sdow-watchnow - margin-top: 6px - float: right + margin-top 6px + float right - /* ugly rule to bypass restrictions */ .seedbox-types[style*="display: none"] + .seedbox-torrents ul a div - max-width: calc(60vw - 100px) - - // Progress container - .progress-wrapper { - position: relative; - padding: 1.5rem 10px 0 10px; - } - - - // General styles - .progress { - height: 8px; - background: $FileSelectorBg; - margin-bottom: $spacer; - overflow: hidden; - border-radius: .2rem !default; - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - - .sr-only { - width: auto; - height: 20px; - margin: 0 0 0 30px; - left: 0; - clip: auto; - line-height: 20px; - font-size: 13px; - } - } - - - // Size variations - .progress-sm { - height: 5px; - } - - .progress-xs { - height: 3px; - } - - // Progress inner elements - .progress-heading { - font-size: 14px; - font-weight: 500; - margin: 0 0 2px; - padding: 0; - } - - .progress-bar { - box-shadow: none; - border-radius: 0; - height: 8px; - width: 0%; - background-color: #fb6340; - background-image: linear-gradient(to bottom, #fb6340 100%, #fb6340 100%); - - &.done { - background-color: #27ae60; - background-image: linear-gradient(to bottom, #27ae60 100%, #27ae60 100%); - } - } + max-width calc(60vw - 100px) + + .progress-wrapper + position relative + padding 1.5rem 10px 0 10px + + .progress + height 8px + background $FileSelectorBg + margin-bottom $spacer + overflow hidden + border-radius .2rem !default + box-shadow inset 0 1px 2px rgba(0, 0, 0, 0.1) + + .sr-only + width auto + height 20px + margin 0 0 0 30px + left 0 + clip auto + line-height 20px + font-size 13px + + .progress-sm + height 5px + + .progress-xs + height 3px + + .progress-heading + font-size 14px + font-weight 500 + margin 0 0 2px + padding 0 + + .progress-bar + box-shadow none + border-radius 0 + height 8px + width 0% + background-color #fb6340 + background-image linear-gradient(to bottom, #fb6340 100%, #fb6340 100%) + + &.done + background-color #27ae60 + background-image linear-gradient(to bottom, #27ae60 100%, #27ae60 100%) .exit-when-done - width: 44px; - margin-top: 21px; - margin-right: -18px; - float: right; - padding: 0.36rem 1rem; - border-radius: 3px; - background: $ShowBgColor2; - color: $ShowText2; - font-size: 0.65rem; - font-weight: 600; - text-transform: uppercase; - overflow: hidden; - text-overflow: clip; - white-space: nowrap; - cursor: pointer; - transition: all 0.7s ease, color 0.3s, background-color 0.3s; - transition-delay: 0.6s, 0s, 0s; + width 44px + margin-top 21px + margin-right -18px + float right + padding 0.36rem 1rem + border-radius 3px + background $ShowBgColor2 + color $ShowText2 + font-size 0.65rem + font-weight 600 + text-transform uppercase + overflow hidden + text-overflow clip + white-space nowrap + cursor pointer + transition all 0.7s ease, color 0.1s, background-color 0.3s + transition-delay 0.6s, 0s, 0s &:hover - width: 35vw; - transition-delay: 0.3s, 0s, 0s; - border-radius: 0; - padding: 0.86rem 1.62rem 0.86rem 1rem; - margin-top: 13px; - margin-right: -28px; + width 35vw + transition-delay 0.3s, 0s, 0s + border-radius 0 + padding 0.86rem 1.62rem 0.86rem 1rem + margin-top 13px + margin-right -28px & > span - opacity: 1; - transition-delay: 0.3s; + opacity 1 + transition-delay 0.3s + + & > i + color $CloseButtonHover &.active - color: #fff; - background-color: #27ae60; + color #fff + background-color #27ae60 + + &:hover + & > i + color #fff &.disabled - visibility: hidden; + display none & i - font-family: "Font Awesome 6 Free"; - font-size: 12px; - float: right; - pointer-events: none; + font-family "Font Awesome 6 Free" + font-size 12px + float right + pointer-events none + transition color 0.3s + margin-top 1px & span - opacity: 0; - transition: opacity 0.5s ease-in-out; - transition-delay: 0.6s; - pointer-events: none; - margin-left: 12px; - - .progress-info { - margin-bottom: .5rem; - display: flex; - align-items: center; - justify-content: space-between; - } - - .progress-label { - span { - display: inline-block; - color: $ShowText2; - font-size: .65rem; - font-weight: 600; - text-transform: uppercase; - background: $FileSelectorBg; - padding: .25rem 1rem; - border-radius: 30px; - } - } - - .progress-percentage { - text-align: right; - color: $ShowText2; - span { - display: inline-block; - color: #e9ecef !default; - font-size: .875rem; - font-weight: 600; - } - } + opacity 0 + transition opacity 0.5s ease-in-out + transition-delay 0.6s + pointer-events none + margin-left 12px + line-height calc(100% + 3px) + + .progress-info + margin-bottom .5rem + display flex + align-items center + justify-content space-between + + .progress-label + span + display inline-block + color $ShowText2 + font-size .65rem + font-weight 600 + text-transform uppercase + background $FileSelectorBg + padding .25rem 1rem + border-radius 30px + + .progress-percentage + text-align right + color $ShowText2 + span + display inline-block + color #e9ecef !default + font-size .875rem + font-weight 600 diff --git a/src/app/styl/views/settings_container.styl b/src/app/styl/views/settings_container.styl index 5ff5ade603..39cfcda34d 100644 --- a/src/app/styl/views/settings_container.styl +++ b/src/app/styl/views/settings_container.styl @@ -5,9 +5,9 @@ width calc(100% - 5px) position fixed scrollable() - padding-top: $TitleHeight + 10px + padding-top $TitleHeight + 10px &::-webkit-scrollbar-track - margin-top: $TitleHeight + margin-top $TitleHeight margin-bottom 5px .settings-container @@ -20,10 +20,10 @@ padding-bottom 20px section - display: flex - flex-direction: row - justify-content: flex-start - flex-flow: row wrap + display flex + flex-direction row + justify-content flex-start + flex-flow row wrap width 92% margin-left auto margin-right auto @@ -81,7 +81,6 @@ &:hover opacity 0 - /* overlay styles, all needed */ .modal-overlay display none position fixed @@ -104,7 +103,7 @@ border-radius 5px border 1px solid $BgColor2 padding 20px 20px 15px - z-index 99999 /* 1px higher than the overlay layer */ + z-index 99999 .modal-close color #000 cursor pointer @@ -141,14 +140,16 @@ margin-top -7px .keyboard,.help,.about - font-size: 21px - margin-right: 25px - color: $Text3 + font-size 21px + margin -3px 22px -3px -3px + padding 3px + border-radius 50% + color $Text3 cursor pointer transition all .5s &:hover - color: $Text1 + color $Text1 transition all .5s #user-interface @@ -200,7 +201,8 @@ .unauthtext, .syncTrakt color $ButtonBgActive - &:hover{ color: $ButtonBgHover; } + &:hover + color $ButtonBgHover #tvshowtime .tvshowtime-options @@ -212,7 +214,8 @@ .unauthtext margin-left 5px color $ButtonBgActive - &:hover{ color: $ButtonBgHover; } + &:hover + color $ButtonBgHover #connect-with-tvst margin-top -12px @@ -243,7 +246,8 @@ .unauthtext margin-left 5px color $ButtonBgActive - &:hover{ color: $ButtonBgHover; } + &:hover + color $ButtonBgHover .loading-spinner animation-duration 0.75s @@ -301,7 +305,9 @@ .content .qr-code font-size 15px - margin-left 158px + margin -3px -3px -3px 155px + padding 3px + border-radius 50% vertical-align middle cursor pointer transition all .5s @@ -350,12 +356,12 @@ #connection #overallRatio - pointer-events: none - -webkit-user-select: none + pointer-events none + -webkit-user-select none i - padding-left: 4px - padding-right: 8px + padding-left 4px + padding-right 8px select padding-left 10px @@ -371,7 +377,7 @@ font-size 13px outline 0 padding-right 10px - width: 62px + width 62px .dropdown-arrow width 0 @@ -386,77 +392,85 @@ cursor pointer .reset-tvAPI - font-size: 13px - color: $SettingsText2 - transition: all .5s + font-size 13px + color $SettingsText2 + transition all .5s &:hover - cursor: pointer - color: $ButtonBgActive - transition: all .5s + cursor pointer + color $ButtonBgActive + transition all .5s #cache .open-tmp-folder, .open-downloads-folder - font-size: 16px - margin-left: 10px - transition: all .5s + font-size 16px + margin -3px -3px -3px 7px + padding 3px + border-radius 50% + transition all .5s &:hover - cursor: pointer - color: $ButtonBgActive - transition: all .5s + cursor pointer + color $ButtonBgActive + transition all .5s .del-seedbox-cache > select - width: 158px + width 158px #database .open-database-folder - font-size: 16px - margin-left: 6px - transition: all .5s + font-size 16px + margin -3px -3px -3px 3px + padding 3px + border-radius 50% + transition all .5s &:hover - cursor: pointer - color: $ButtonBgActive - transition: all .5s + cursor pointer + color $ButtonBgActive + transition all .5s .import-db - margin-left: 7px - padding: 0 1px - cursor: pointer - transition: all .5s + margin -3px -3px -3px 4px + padding 3px 4px + border-radius 50% + cursor pointer + transition all .5s &:hover - color: $ButtonBgActive + color $ButtonBgActive .export-database - margin-left: 1px - padding: 0 1px - cursor: pointer - transition: all .5s + margin -3px -3px -3px -2px + padding 3px 4px + border-radius 50% + cursor pointer + transition all .5s &:hover - color: $ButtonBgActive + color $ButtonBgActive .set-current-filter, .reset-current-filter, .update-dht, .update-app - font-size: 13px - margin: 0 2px 0 8px - transition: all 0.5s - cursor: pointer + font-size 13px + margin -3px -1px -3px 5px + padding 3px + border-radius 50% + transition all 0.5s + cursor pointer &:hover - color: $ButtonBgActive + color $ButtonBgActive .closeTraktCode - font-size: 13px - margin: 0 2px 0 8px - transition: all 0.5s - cursor: pointer + font-size 13px + margin 0 2px 0 8px + transition all 0.5s + cursor pointer &:hover - color: #ee3030 + color #ee3030 .reset-current-filter.disabled - color: inherit - opacity: 0.3 - cursor: default + color inherit + opacity 0.3 + cursor default .btns padding-top 10px @@ -487,7 +501,7 @@ &> label cursor pointer &.database - margin-top: 0 + margin-top 0 &:hover background-color $ButtonBgHover color $SettingsButtonTextHover @@ -504,8 +518,8 @@ &.warning background-color $ButtonBgWarning &:active - box-shadow: inset 0 1px 4px rgba(0,0,0,0.6) - background: $ButtonBgActive + box-shadow inset 0 1px 4px rgba(0,0,0,0.6) + background $ButtonBgActive .dropdown select @@ -589,77 +603,77 @@ outline 0 !important &#fakedatabaseLocation - pointer-events: none - -webkit-user-select: none + pointer-events none + -webkit-user-select none &#fakedatabaseLocation,&#settingsIpAddr - pointer-events: none - -webkit-user-select: none + pointer-events none + -webkit-user-select none input[type='color'] - -webkit-appearance: none + -webkit-appearance none width 62px input[type='color']::-webkit-color-swatch - margin: 3px -9px 3px -3px + margin 3px -9px 3px -3px input[type='number']::-webkit-inner-spin-button - -webkit-appearance: none - margin: 0 + -webkit-appearance none + margin 0 input[type=checkbox] &.settings-checkbox - position: absolute - overflow: hidden - clip: rect(0 0 0 0) - height:1px - width:1px - margin:-1px - padding:0 - border:0 + position absolute + overflow hidden + clip rect(0 0 0 0) + height 1px + width 1px + margin -1px + padding 0 + border 0 &.settings-checkbox+label.settings-label - height:15px - display:inline-block - line-height:15px - font-size:13px - font-family: $Font, $AlternateFont - vertical-align:middle - cursor:pointer - color:$SettingsText1 + height 15px + display inline-block + line-height 15px + font-size 13px + font-family $Font, $AlternateFont + vertical-align middle + cursor pointer + color $SettingsText1 &.settings-checkbox:checked+label.settings-label &:after - opacity: 1 + opacity 1 input[type="text"] &#downloadLimit - width: 78px + width 78px &#uploadLimit - width: 78px - margin-left: 7px + width 78px + margin-left 7px .settings-label &:before - content: '\f0c8' - font-family: "Font Awesome 6 Free" - font-weight: 900 - font-size: 18px - padding-right: 8px - float: left - position: relative - color: $CheckboxBg + content '\f0c8' + font-family "Font Awesome 6 Free" + font-weight 900 + font-size 18px + padding-right 8px + float left + position relative + color $CheckboxBg &:after - content: '\f00c' - font-family: "Font Awesome 6 Free" - font-weight: 900 - font-size: 12px - margin-right: -14px - color: $CheckboxCheck - position: relative - float: left - left: -21px - opacity: 0 - transition: opacity .1s ease-in-out + content '\f00c' + font-family "Font Awesome 6 Free" + font-weight 900 + font-size 12px + margin-right -14px + color $CheckboxCheck + position relative + float left + left -21px + opacity 0 + transition opacity .1s ease-in-out .settings-container-check-settings width 14px @@ -703,9 +717,9 @@ .settings-container section &.advanced - display: none + display none .advanced - display: none + display none .default-frame .settings-container-contain @@ -713,6 +727,6 @@ .close-icon top 5px &::-webkit-scrollbar-track - margin-top: $FilterBarHeight + margin-top $FilterBarHeight .close-icon top 45px diff --git a/src/app/styl/views/show_detail.styl b/src/app/styl/views/show_detail.styl index f4a7d2ef5a..466c2bcc1b 100644 --- a/src/app/styl/views/show_detail.styl +++ b/src/app/styl/views/show_detail.styl @@ -1,39 +1,39 @@ .show-detail-container - display: flex - position: fixed - width: 100% - padding-top: 67px - background: $BgColor1 - flex-direction: column + display flex + position fixed + width 100% + padding-top 67px + background $BgColor1 + flex-direction column .show-header - width: 100vw - /*height: 25vh TODO: responsive header (especially poster)*/ - min-height: 215px + width 100vw + min-height 215px .sh-backdrop .shb-img - position: absolute - min-height: calc(100% - 67px) - width: 100vw - background-repeat: no-repeat - background-size: cover - background-position: center - -webkit-filter: blur(60px) brightness(0.7) + position absolute + min-height 100% + margin-top -35px + width 100vw + background-repeat no-repeat + background-size cover + background-position center + -webkit-filter blur(60px) brightness(0.7) background-color $ShowBgColor1 - opacity: 0 + opacity 0 &.fadein - transition: opacity .3s ease-in; - opacity: 1 + transition opacity .3s ease-in + opacity 1 .sh-poster - float: left - width: 198px - height: 100% - z-index: 20 - position: relative - pointer-events: none - transition: transform 0.05s ease-out + float left + width 198px + height 100% + z-index 20 + position relative + pointer-events none + transition transform 0.05s ease-out .shp-img position relative @@ -51,22 +51,22 @@ pointer-events auto cursor pointer &.fadein - transition: opacity .3s ease-in; - opacity: 1 + transition opacity .3s ease-in + opacity 1 .sh-poster.active - transition: transform 0.12s ease-out + transition transform 0.12s ease-out .shp-img - border-radius: 2px + border-radius 2px .sh-metadata - float: left - position: relative - height: 194px - width: calc(100% - 198px) - padding-top: 10px - padding-right: 45px + float left + position relative + height 194px + width calc(100% - 198px) + padding-top 10px + padding-right 45px .shm-title color #fff @@ -74,63 +74,63 @@ -webkit-font-smoothing antialiased font-size 28px margin-bottom 8px - margin-top: 5px + margin-top 5px .shm-infos div - float: left - font-size: 11px - font-family: $MainFontBold - color: #fff - -webkit-font-smoothing: antialiased + float left + font-size 11px + font-family $MainFontBold + color #fff + -webkit-font-smoothing antialiased &:not(.shmi-tmdb-link) &:hover ~ div.shmi-tmdb-link - opacity: 0.4 - transition-delay: .8s + opacity 0.4 + transition-delay .8s div.shmi-year - cursor: pointer + cursor pointer div.shmi-tmdb-link - padding-left: 12px - padding-right: 6px - cursor: pointer - opacity: 0 - transition: opacity .3s ease-in - transition-delay: .2s + padding-left 12px + padding-right 6px + cursor pointer + opacity 0 + transition opacity .3s ease-in + transition-delay .2s &:hover - opacity: 1 - transition-delay: 0s + opacity 1 + transition-delay 0s &.disabled &:hover - cursor: default - opacity: 0.4 + cursor default + opacity 0.4 div.shmi-imdb - cursor: pointer - background: url(../images/icons/imdb.png) no-repeat - width: 27px - height: 16px - position: relative - top: -2px + cursor pointer + background url(../images/icons/imdb.png) no-repeat + width 27px + height 16px + position relative + top -2px div.shmi-rating - cursor: pointer + cursor pointer .hidden - display: none + display none .number-container-tv - position: relative - font-size: 12px - font-family: $MainFontBold - color: #FFF + position relative + font-size 12px + font-family $MainFontBold + color #FFF em - font-size: 0.8em + font-size 0.8em .star-container-tv position relative @@ -139,30 +139,30 @@ .rating-star color #ffc900 font-size 11px - padding-right: 3px + padding-right 3px .rating-star-half color #ffc900 font-size 11px margin-left -4px - padding-right: 3px + padding-right 3px .rating-star-half-empty color #a3a5a7 font-size 11px - margin-left: -4px + margin-left -4px .rating-star-empty color #a3a5a7 font-size 11px - padding-right: 3px + padding-right 3px .rating-star-half-container width 1em height 1em line-height 1em - margin-top: -3px; - margin-left: 4px; + margin-top -3px + margin-left 4px span.dot margin 4.5px 15px 0 15px @@ -175,221 +175,221 @@ cursor default .shm-synopsis - color: #fff - float: left - width: 100% - text-align: justify - font-family: $MainFont - -webkit-font-smoothing: antialiased - font-size: 12px - line-height: 22px - max-height: 107px - padding-right: 8px - margin-top: 8px - overflow: hidden + color #fff + float left + width 100% + text-align justify + font-family $MainFont + -webkit-font-smoothing antialiased + font-size 12px + line-height 22px + max-height 107px + padding-right 8px + margin-top 8px + overflow hidden scrollable() .sh-metadata.active - filter: blur(4px) - pointer-events: none + filter blur(4px) + pointer-events none .sh-actions - float: left - position: relative - width: calc(100% - 198px) - height: 35px - margin-top: -15px + float left + position relative + width calc(100% - 198px) + height 35px + margin-top -15px padding-right 45px - display: flex - flex-direction: row - justify-content: space-between - white-space: nowrap + display flex + flex-direction row + justify-content space-between + white-space nowrap .dropdowns-container - margin: -10px -30px 0 0 + margin -10px -30px 0 0 #audio-dropdown .lang-dropdown - background: none + background none .sha-bookmark - float: left - cursor: pointer - padding-left: 24px - color: #FFF - position: relative - font-family: $MainFont - font-smoothing: antialiased - font-size: 12px - line-height: 37px - margin-top: -2px + float left + cursor pointer + padding-left 24px + color #FFF + position relative + font-family $MainFont + font-smoothing antialiased + font-size 12px + line-height 37px + margin-top -2px &:before - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: #FFF - top: 0 - left: 0 - bottom: 0 - right: 0 - opacity: 1 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color #FFF + top 0 + left 0 + bottom 0 + right 0 + opacity 1 + transition opacity 0.5s &:after - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: $ButtonBgActive - top: 0 - left: 0 - bottom: 0 - right: 0 - opacity: 0 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color $ButtonBgActive + top 0 + left 0 + bottom 0 + right 0 + opacity 0 + transition opacity 0.5s &:hover &:before - opacity: 0 + opacity 0 &:after - opacity: 1 + opacity 1 &.selected - height: 18px - width: 200px + height 18px + width 200px &:before - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: $FavoriteColor - top: 0 - left: 0 - bottom: 0 - right: 0 - opacity: 1 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color $FavoriteColor + top 0 + left 0 + bottom 0 + right 0 + opacity 1 + transition opacity 0.5s &:after - content: "\f004" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: #FFF - top: 0 - left: 0 - bottom: 0 - right: 0 - opacity: 0 - transition: opacity 0.5s + content "\f004" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color #FFF + top 0 + left 0 + bottom 0 + right 0 + opacity 0 + transition opacity 0.5s &:hover &:before - opacity: 0 + opacity 0 &:after - opacity: 1 + opacity 1 .sha-watched - float: left - cursor: pointer - padding-left: 28px - margin-left: 20px - color: #FFF - position: relative - font-family: $MainFont - font-smoothing: antialiased - font-size: 12px - line-height: 37px - margin-top: -2px - display: none + float left + cursor pointer + padding-left 28px + margin-left 20px + color #FFF + position relative + font-family $MainFont + font-smoothing antialiased + font-size 12px + line-height 37px + margin-top -2px + display none &:before - content: "\f070" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 18px - color: #FFF - left: 0 - opacity: 1 - transform: scaleY(0.9) - transition: opacity 0.5s + content "\f070" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 18px + color #FFF + left 0 + opacity 1 + transform scaleY(0.9) + transition opacity 0.5s &:after - content: "\f00c" - font-family: "Font Awesome 6 Free" - font-weight: 900 - position: absolute - font-size: 20px - color: #299000 - left: 0 - opacity: 0 - transition: opacity 0.5s + content "\f00c" + font-family "Font Awesome 6 Free" + font-weight 900 + position absolute + font-size 20px + color #299000 + left 0 + opacity 0 + transition opacity 0.5s &:hover, &.selected &:before - opacity: 0 + opacity 0 &:after - opacity: 1 + opacity 1 .sh-actions.active - filter: blur(4px) - pointer-events: none + filter blur(4px) + pointer-events none .show-details - width: 100vw - z-index: 1 - background: rgba($ShowBgColor1, 0.7) - height: calc(100vh - 282px) - display: grid - padding-left: 20px /* left-pad */ - gap: 10px; - grid-template-columns: fit-content(165px) 2fr minmax(480px, 1fr); - grid-template-rows: 2fr auto; - grid-template-areas: "seasons episodes overview" "torrents torrents overview"; + width 100vw + z-index 1 + background rgba($ShowBgColor1, 0.7) + height calc(100vh - 282px) + display grid + padding-left 20px + gap 10px + grid-template-columns fit-content(165px) 2fr minmax(480px, 1fr) + grid-template-rows 2fr auto + grid-template-areas "seasons episodes overview" "torrents torrents overview" &.transpOff - background: $ShowBgColor1 + background $ShowBgColor1 &.transpVLow - background: rgba($ShowBgColor1, 0.9) + background rgba($ShowBgColor1, 0.9) &.transpLow - background: rgba($ShowBgColor1, 0.8) + background rgba($ShowBgColor1, 0.8) &.transpHigh - background: rgba($ShowBgColor1, 0.6) + background rgba($ShowBgColor1, 0.6) &.transpVHigh - background: rgba($ShowBgColor1, 0.5) + background rgba($ShowBgColor1, 0.5) .sd-seasons ul, .sd-episodes ul - position: absolute; - top:45px; - bottom:0; - cursor: pointer - direction: rtl - white-space: nowrap + position absolute + top 45px + bottom 0 + cursor pointer + direction rtl + white-space nowrap scrollable() li - padding: 0px 15px - margin: 1px 0px 1px 1px - float: left - width: calc(100% - 7px) + padding 0px 15px + margin 1px 0px 1px 1px + float left + width calc(100% - 7px) .watched padding 9px 0 - color: $ShowWatchedIcon_false + color $ShowWatchedIcon_false transition color .5s &:hover - color: $ShowWatchedIcon_hover + color $ShowWatchedIcon_hover &.true - color: $ShowWatchedIcon_true + color $ShowWatchedIcon_true li:nth-child(odd) background-color rgba($ShowOddHighlight, $ShowOddHighlightOp) @@ -402,7 +402,7 @@ background rgba($EpisodeSelectorHoverTran,20%) li:not(.active).transpOff:hover - background: $EpisodeSelectorHover + background $EpisodeSelectorHover li.active background-color $EpisodeSelectorBg @@ -420,266 +420,270 @@ border-width 16px 6px 17px 6px a - text-decoration: none - font-size: 15px - line-height: 34px - font-weight: normal - float: left - flex-direction: row - direction: ltr + text-decoration none + font-size 15px + line-height 34px + font-weight normal + float left + flex-direction row + direction ltr span - float: left - margin: 0px 15px 0px 5px + float left + margin 0px 15px 0px 5px div - white-space: nowrap - border-left: 1px solid $ShowBgColor1 - padding-left: 30px - text-align: left - overflow: hidden - text-overflow: ellipsis + white-space nowrap + border-left 1px solid $ShowBgColor1 + padding-left 30px + text-align left + overflow hidden + text-overflow ellipsis .sd-seasons, .sd-episodes - position: relative; - height: 100%; + position relative + height 100% .sds-title, .sde-title - font-size: 24px - overflow: hidden - text-overflow: ellipsis - white-space: nowrap - margin-bottom: 15px - margin-top: 2px - color: $ShowText1 + font-size 24px + overflow hidden + text-overflow ellipsis + white-space nowrap + margin-bottom 15px + margin-top 2px + color $ShowText1 .sd-seasons - min-width: 165px - padding: 10px + min-width 165px + padding 10px .sds-list ul a - color: $SaisonListText - font-family: $AlternateFont - white-space: nowrap + color $SaisonListText + white-space nowrap + + .sds-list ul li.active a + color $EpisodeSelectorText .sd-episodes - grid-area: episodes; - padding: 10px + grid-area episodes + padding 10px .sde-list ul - width: calc(100% - 10px) + width calc(100% - 10px) .sde-list ul li a - color: $EpisodeListText - font-family: $MainFont - min-width: 70px - max-width: calc(60vw - 290px) + color $EpisodeListText + font-family $MainFont + min-width 70px + max-width calc(60vw - 290px) .sde-list ul li.active a - color: $EpisodeSelectorText + color $EpisodeSelectorText .sd-overview - background: rgba($ShowBgColor1, 0.3) - grid-area: overview; - padding: 10px 30px 10px 18px /* right pad */ - display: grid - grid-template-rows: auto 2fr + background rgba($ShowBgColor1, 0.3) + grid-area overview + padding 10px 30px 10px 18px + display grid + grid-template-rows auto 2fr &.transpOff - background: $ShowBgColor2 + background $ShowBgColor2 .sdo-infos - height: fit-content - overflow-x: hidden + height fit-content + overflow-x hidden .sdoi-title - overflow: hidden - white-space: nowrap - text-overflow: ellipsis - font-size: 24px - margin-top: 2px - padding-bottom: 6px - color: $ShowText1 + overflow hidden + white-space nowrap + text-overflow ellipsis + font-size 24px + margin-top 2px + padding-bottom 6px + color $ShowText1 .sdoi-links - position: absolute - right: 42px - margin-top: -6px + position absolute + right 42px + margin-top -6px &>div - padding: 5px 3px - cursor: pointer - position: relative + padding 5px 3px + border-radius 50% + cursor pointer + position relative .health-icon - font-size: 14px - color: #737577 - transition: all .3s ease-in + font-size 14px + color #737577 + transition all .3s ease-in &.Bad - color: #d53f3f + color #d53f3f &.Medium - color: #ece523 + color #ece523 &.Good - color: #a3e147 + color #a3e147 &.Excellent - color: #2ad942 + color #2ad942 .magnet-icon - font-size: 13px - color: #DDD - margin-right: 2px + font-size 13px + color #DDD + margin-right 2px &:hover - color: #FFF - transition: all .5s + color #FFF + transition all .5s .source-icon - display: inline-block - font-size: 13px - color: #DDD - margin-right: 0px - top: 3px + display inline-block + font-size 13px + color #DDD + margin-right 0px + top 3px &:hover - color: #FFF - transition: all .5s + color #FFF + transition all .5s img - height: 16px + height 16px .sdoi-aired - font-size: 12px - line-height: 15px - margin-bottom: 10px - color: $ShowText2 + font-size 12px + line-height 15px + margin-bottom 10px + color $ShowText2 .sdoi-date - overflow: hidden - white-space: nowrap - text-overflow: ellipsis + overflow hidden + white-space nowrap + text-overflow ellipsis .sdoi-synopsis - color: $ShowText1 - font-size: 13px - line-height: 18px - text-align: justify - margin-top: 10px - padding: 2px 15px 5px 0 - height: fit-content + color $ShowText1 + font-size 13px + line-height 18px + text-align justify + margin-top 10px + padding 2px 15px 5px 0 + height fit-content scrollable() #torrent-list - height: auto - margin: 10px -10px 10px -5px + height auto + margin 10px -10px 10px -5px .sdo-watch - height: 60px - padding: 5px 0px 15px 0px - margin-bottom: -5px + height 60px + padding 5px 0px 15px 0px + margin-bottom -5px &.disabled - margin-bottom: 50px + margin-bottom 50px .play-selector - position: relative - float: right - margin-top: 6px + position relative + float right + margin-top 6px &.disabled - position: absolute - right: 5px - margin-top: -5px - cursor: pointer - opacity: 1 - filter: none + position absolute + right 5px + margin-top -5px + cursor pointer + opacity 1 + filter none .show-all-torrents - float: left - font-family: $MainFont - -webkit-font-smoothing: antialiased - font-size: 11px - color: $ShowText1 - transition: all .2s ease-in, margin 0s - padding: 0 6px - margin: 13px 6px 0 0 - border-radius: 10px - height: 19px - line-height: 19px - cursor: pointer + float left + font-family $MainFont + -webkit-font-smoothing antialiased + font-size 11px + color $ShowText1 + transition all .2s ease-in, margin 0s + padding 0 6px + margin 13px 6px 0 0 + border-radius 10px + height 19px + line-height 19px + cursor pointer &:hover, &.active - color: $QualitySelectorText - background: $QualitySelectorBg + color $QualitySelectorText + background $QualitySelectorBg &.fa-spinner - font-family: "Font Awesome 6 Free" - transition: none - margin-left: 6px + font-family "Font Awesome 6 Free" + transition none + margin-left 6px + color $ShowText1 &:hover, &.active - background: none + background none .sdow-quality - margin-top: 13px - float: left + margin-top 13px + float left div - cursor: pointer - float: left - font-family: $MainFont; - -webkit-font-smoothing: antialiased; - font-size: 11px - color: $ShowText1 - transition: all .2s ease-in - padding: 4px - margin-right: 6px + cursor pointer + float left + font-family $MainFont + -webkit-font-smoothing antialiased + font-size 11px + color $ShowText1 + transition all .2s ease-in + padding 4px + margin-right 6px .disabled - opacity: .3 - cursor: default + opacity .3 + cursor default .active - cursor: pointer - opacity: 1 - color: $QualitySelectorText - background: $QualitySelectorBg - border-radius: 10px - font-family: $MainFontBold + cursor pointer + opacity 1 + color $QualitySelectorText + background $QualitySelectorBg + border-radius 10px + font-family $MainFontBold .sdow-watchnow - margin-top: 6px - float: right + margin-top 6px + float right &.disabled - visibility: hidden + visibility hidden #player-chooser .button - margin-right: 0px + margin-right 0px .sd-torrents - grid-area: torrents - max-height: 300px + grid-area torrents + max-height 300px .action - color: rgba(0,0,0,0) !important - width: 0px !important - padding: 0px !important - pointer-events: none + color rgba(0,0,0,0) !important + width 0px !important + padding 0px !important + pointer-events none .item-download - font-family: $Font, $AlternateFont + font-family $Font, $AlternateFont > .spinner - position: fixed; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.5) center center no-repeat; - pointer-events: all; - z-index: 1; + position fixed + width 100% + height 100% + background rgba(0, 0, 0, 0.5) center center no-repeat + pointer-events all + z-index 1 .loading-container - margin: 180px auto 0px - opacity: .8; + margin 180px auto 0px + opacity .8 .show-details.active - filter: brightness(50%) blur(4px) - pointer-events: none + filter brightness(50%) blur(4px) + pointer-events none diff --git a/src/app/styl/views/title_bar.styl b/src/app/styl/views/title_bar.styl index 93cdf3ff7d..61c8cbd702 100644 --- a/src/app/styl/views/title_bar.styl +++ b/src/app/styl/views/title_bar.styl @@ -1,130 +1,129 @@ #header - z-index: 10 - position: absolute - top: 0 - width: 100% - opacity: 1 - height: $TitleHeight - background-color: $TitleBarBg - padding: 13px 0 0 - text-align: center - -webkit-app-region: drag + z-index 10 + position absolute + top 0 + width 100% + opacity 1 + height $TitleHeight + background-color $TitleBarBg + padding 13px 0 0 + text-align center + -webkit-app-region drag .tooltip - white-space: nowrap + white-space nowrap h1 - color: $TitleBarText - font-size: 0.9em - top: -3px - position: relative + color $TitleBarText + font-size 0.9em + top -3px + position relative .btn-set - position: absolute; - left: 15px; - z-index: 10; + position absolute + left 15px + z-index 10 - // Changes the min/max/close button position depending on OS nav - -webkit-app-region: no-drag + -webkit-app-region no-drag &.darwin - position: absolute; - left: 15px; + position absolute + left 15px &.fs-darwin - top: 0px; - right: 7px; - left: initial; + top 0px + right 7px + left initial &.win32, &.linux - right: 7px; - left: initial; + right 7px + left initial &.fs-win32, &.fs-linux - position: absolute; - left: 2px; - top: 2px; + position absolute + left 2px + top 2px .btn-os - float: left - margin: 0 6px 0 0 - background-color: #000 - background-size: 77px 12px - background-image: url('../images/icons/topbar_sprite.png') - border-radius: 30px - border: 0 - color: transparent - display: inline-block - font-size: 10px - height: 12px - padding: 0 - text-align: center - width: 12px - cursor: pointer + float left + margin 0 6px 0 0 + background-color #000 + background-size 77px 12px + background-image url('../images/icons/topbar_sprite.png') + border-radius 30px + border 0 + color transparent + display inline-block + font-size 10px + height 12px + padding 0 + text-align center + width 12px + cursor pointer &.os-min - background-position: 0px 0px; + background-position 0px 0px &.os-max - background-position: -13px 0px; + background-position -13px 0px &.os-close - background-position: -26px 0px; + background-position -26px 0px &.os-min:hover - background-position: -39px 0px; + background-position -39px 0px &.os-max:hover - background-position: -52px 0px; + background-position -52px 0px &.os-close:hover - background-position: -65px 0px; + background-position -65px 0px &.fullscreen - color:$FullScreenButton; - background: transparent; - margin:0; - z-index: 10; - width:30px; - height:28px; - border-radius:0; - display:block; + color $FullScreenButton + background transparent + margin 0 + z-index 10 + width 30px + height 28px + border-radius 0 + display block &.fullscreen::before - content: "\e000"; - font-family: VideoJS; - font-size: 1.85em; - line-height: 0.2em; - background: none; - display:block; - text-shadow: 0 1px 0 rgba(255,255,255,0.1) + content "\e000" + font-family VideoJS + font-size 1.85em + line-height 0.2em + background none + display block + text-shadow 0 1px 0 rgba(255,255,255,0.1) &.fullscreen.active::before - content: "\e00B"; + content "\e00B" &.fullscreen:hover - color:$FullScreenButtonHover; + color $FullScreenButtonHover .btn-set.win32 - background-size: auto auto - top: 0px - right: 0px + background-size auto auto + top 0px + right 0px .btn-os - float: left - margin: 0 - background-color: transparent - -webkit-border-radius: 0px - border-radius: 0px - border: 0 - color: transparent - display: inline-block - font-size: 10px - height: 32px - padding: 0 - text-align: center - width: 40px - cursor: pointer - background-image: url("../images/icons/topbar_sprite_win.png") - background-size: cover + float left + margin 0 + background-color transparent + -webkit-border-radius 0px + border-radius 0px + border 0 + color transparent + display inline-block + font-size 10px + height 32px + padding 0 + text-align center + width 40px + cursor pointer + background-image url("../images/icons/topbar_sprite_win.png") + background-size cover -webkit-filter $PngLogo &.os-close background-position -80px 0px @@ -146,66 +145,65 @@ background-position -120px 0px -webkit-filter brightness(1) - .btn-set.darwin .btn-os - background-image: none - background-repeat: no-repeat + background-image none + background-repeat no-repeat &.os-close - background-color: #FC5753 + background-color #FC5753 &.os-max - background-color: #33C748 + background-color #33C748 &.os-min - background-color: #FDBC40 + background-color #FDBC40 &:hover .btn-os - background-image: url('../images/icons/topbar_sprite.png') + background-image url('../images/icons/topbar_sprite.png') &.os-min - background-position: -39px 0px; + background-position -39px 0px &.os-max - background-position: -52px 0px; + background-position -52px 0px &.os-close - background-position: -65px 0px; + background-position -65px 0px .header-shadow - box-shadow: $TopBarShadow + box-shadow $TopBarShadow .events - width: 28px - height: 28px - position: absolute - top: -6px - left: calc(50% + 52px) - display: none; + width 28px + height 28px + position absolute + top -6px + left calc(50% + 52px) + display none &.img-newyear - background: URL('../images/events/newyear.png') - background-repeat: no-repeat - background-size: 28px 28px + background URL('../images/icons/events/newyear.png') + background-repeat no-repeat + background-size 28px 28px &.img-pt_anniv - background: URL('../images/events/pt_anniv.png') - background-repeat: no-repeat - background-size: 28px 28px + background URL('../images/icons/events/pt_anniv.png') + background-repeat no-repeat + background-size 28px 28px &.img-halloween - background: URL('../images/events/halloween.png') - background-repeat: no-repeat - background-size: 28px 28px + background URL('../images/icons/events/halloween.png') + background-repeat no-repeat + background-size 28px 28px &.img-stvalentine - background: URL('../images/events/stvalentine.png') - background-repeat: no-repeat - background-size: 48px 28px - width: 48px - height: 28px + background URL('../images/icons/events/stvalentine.png') + background-repeat no-repeat + background-size 48px 28px + width 48px + height 28px &.img-stpatrick - background: URL('../images/events/stpatrick.png') - background-repeat: no-repeat - background-size: 28px 28px + background URL('../images/icons/events/stpatrick.png') + background-repeat no-repeat + background-size 28px 28px &.img-aprilsfool - background: URL('../images/events/aprilsfool.png') - background-repeat: no-repeat - background-size: 28px 28px + background URL('../images/icons/events/aprilsfool.png') + background-repeat no-repeat + background-size 28px 28px &.img-xmas - background: URL('../images/events/xmas.png') - background-repeat: no-repeat - background-size: 28px 28px + background URL('../images/icons/events/xmas.png') + background-repeat no-repeat + background-size 28px 28px diff --git a/src/app/styl/views/torrent-list.styl b/src/app/styl/views/torrent-list.styl deleted file mode 100644 index 5165c46f06..0000000000 --- a/src/app/styl/views/torrent-list.styl +++ /dev/null @@ -1,118 +0,0 @@ -#torrent-list, #torrent-show-list - overflow: auto - color: $Text1 - font-size: 13px - overflow-x: hidden - overflow-y: overlay - -webkit-overflow-scrolling: touch - - &::-webkit-scrollbar - width: 5px - - &::-webkit-scrollbar-track - background-color: $ScrollBarBg - border-radius: 2px - margin-top: 10px - margin-bottom: 10px - - &::-webkit-scrollbar-thumb - background-color: $ScrollBarThumb - border-radius: 2px - - &:hover - background-color: $ScrollBarThumbHover - - &::-webkit-resizer, - &::-webkit-scrollbar-corner, - &::-webkit-scrollbar-button, - &::-webkit-scrollbar-track-piece - display: none - - table - width: 100% - table-layout: auto - tr - cursor: pointer - - &:nth-of-type(odd) - td - background: rgba(0,0,0,0) - - &:hover > - td - background: rgba($EpisodeSelectorHoverTran,20%) - - td.transpOff - background: $EpisodeSelectorHover - - &.disabled - cursor: not-allowed - opacity: 0.7 - filter: grayscale(30%) - - td - padding: 3px - color: $EpisodeListText - - &.ellipsis - position: relative - &.ellipsis:before - content: ' ' - visibility: hidden - &.ellipsis span - position: absolute - left: 0 - right: 0 - white-space: nowrap - overflow: hidden - text-overflow: ellipsis - max-width: fit-content - margin-top: -9px - padding: 9px 3px 9px 0 - - &.provider - width: 35px - line-height: 30px - padding-left: 8px - img - cursor: pointer - height: 16px - vertical-align: top - margin-top: 7px - - &.info - width:0.1% - white-space: nowrap - text-align: right - padding: 3px 10px - &.action - width: 40px - cursor: pointer - padding-left: 8px - - &:hover - color: $ShowText1 - transition: color .5s - -#torrent-show-list - font-size: 15px - margin: 6px 1px 19px 0px - max-height: 281px - - table - td - &.info, &.action - color: $ShowWatchedIcon_false - - tr:nth-of-type(odd) - td - background: rgba($ShowOddHighlight, $ShowOddHighlightOp) - &.transpOff - background: $ShowBgColor2 - - &:hover > - td - background: rgba($EpisodeSelectorHoverTran,20%) - - td.transpOff - background: $EpisodeSelectorHover diff --git a/src/app/styl/views/torrent_collection.styl b/src/app/styl/views/torrent_collection.styl index 6466bf9943..5935468c1a 100644 --- a/src/app/styl/views/torrent_collection.styl +++ b/src/app/styl/views/torrent_collection.styl @@ -7,17 +7,16 @@ opacity 1 > .spinner - position: fixed; - width: 100%; - height: 100%; - background: rgba(0, 0, 0, 0.4) center center no-repeat; - backdrop-filter: blur(4px); - pointer-events: all; - z-index: 1; + position fixed + width 100% + height 100% + background rgba(0, 0, 0, 0.4) center center no-repeat + pointer-events all + z-index 1 .loading-container - margin: 50vh auto 0px - opacity: .8; + margin 50vh auto 0px + opacity .8 .margintop height 100px @@ -174,15 +173,6 @@ cursor pointer transition opacity .1s ease-in - &#kat-icon - background url('../images/icons/kickasstorrents.png') - background-size contain - - &#strike-icon - -webkit-filter $PngLogo_BgColo1 - background url('../images/icons/getstrike.png') - background-size contain - &.active opacity 1 @@ -192,16 +182,18 @@ background-color $InputBoxBg resize none color $InputBoxText - font-family $Font, $AlternateFont + font-family $MainFont, $AlternateFont font-size 13px padding-left 10px cursor text outline 0 !important height 30px min-width 410px + margin-right 2px .online-search - margin-left 5px + padding 5px 0 5px 5px + border-radius 50% cursor pointer color $SettingsText1 opacity 0.5 @@ -246,7 +238,7 @@ background-color $InputBoxBg cursor pointer color $InputBoxText - font-family $Font, $AlternateFont + font-family $MainFont, $AlternateFont font-size 13px float left outline 0 @@ -304,16 +296,17 @@ .online-back position fixed - font-size 25px - color $TextError + font-size 0.9em + color $FilterBarIcon cursor pointer - right 7% - top 152px + left 50% + top 105px + margin-left 205px + padding 3px 5px + border-radius 50% + z-index 10 transition color .3s - &:hover - color $Text1 - ul &.file-list overflow hidden @@ -331,6 +324,7 @@ padding-right 50px font-family $MainFont font-size 15px + overflow hidden &:nth-child(odd) background $ShowBgColor2 @@ -362,14 +356,16 @@ opacity 0.12 transition all 0.3s cursor pointer - left calc(100% + 22px) - top -42px + left calc(100% + 18px) + top -58px + padding 3px + border-radius 50% &:hover opacity 1 .item-rename - left calc(100% - 25px) + left calc(100% - 38px) .item-icon position relative @@ -381,9 +377,10 @@ width 15px color $SettingsText1 opacity 0.7 - left -25px - top -27px + left -33px + top -35px transition opacity .3s + padding 8px 20px 20px 8px &.torrent-icon:before content '\f15b' @@ -406,9 +403,9 @@ opacity 0.5 font-style normal font-size .9em - left calc(100% - 180px) - top -42px - min-width 100px + left calc(100% - 150px) + top -55px + min-width 90px text-align right display inline-block @@ -418,8 +415,8 @@ opacity 0.5 font-style normal font-size .9em - left calc(100% - 155px) - top -42px + left calc(100% - 135px) + top -55px min-width 70px text-align right display inline-block @@ -440,7 +437,7 @@ .collection-actions position absolute color $SettingsText1 - top 5px + top 6px margin-left 462px .collection-paste, @@ -449,6 +446,7 @@ cursor pointer opacity 0.3 padding 0 5px 8px 5px + border-radius 50% &:hover opacity 1 diff --git a/src/app/styl/views/torrent_list.styl b/src/app/styl/views/torrent_list.styl new file mode 100644 index 0000000000..181ee11b7b --- /dev/null +++ b/src/app/styl/views/torrent_list.styl @@ -0,0 +1,118 @@ +#torrent-list, #torrent-show-list + overflow auto + color $Text1 + font-size 13px + overflow-x hidden + overflow-y overlay + -webkit-overflow-scrolling touch + + &::-webkit-scrollbar + width 5px + + &::-webkit-scrollbar-track + background-color $ScrollBarBg + border-radius 2px + margin-top 10px + margin-bottom 10px + + &::-webkit-scrollbar-thumb + background-color $ScrollBarThumb + border-radius 2px + + &:hover + background-color $ScrollBarThumbHover + + &::-webkit-resizer, + &::-webkit-scrollbar-corner, + &::-webkit-scrollbar-button, + &::-webkit-scrollbar-track-piece + display none + + table + width 100% + table-layout auto + tr + cursor pointer + + &:nth-of-type(odd) + td + background rgba(0,0,0,0) + + &:hover > + td + background rgba($EpisodeSelectorHoverTran,20%) + + td.transpOff + background $EpisodeSelectorHover + + &.disabled + cursor not-allowed + opacity 0.7 + filter grayscale(30%) + + td + padding 3px + color $EpisodeListText + + &.ellipsis + position relative + &.ellipsis:before + content ' ' + visibility hidden + &.ellipsis span + position absolute + left 0 + right 0 + white-space nowrap + overflow hidden + text-overflow ellipsis + max-width fit-content + margin-top -9px + padding 9px 3px 9px 0 + + &.provider + width 35px + line-height 30px + padding-left 8px + img + cursor pointer + height 16px + vertical-align top + margin-top 7px + + &.info + width 0.1% + white-space nowrap + text-align right + padding 3px 10px + &.action + width 40px + cursor pointer + padding-left 8px + + &:hover + color $ShowText1 + transition color .5s + +#torrent-show-list + font-size 15px + margin 6px 1px 19px 0px + max-height 281px + + table + td + &.info, &.action + color $ShowWatchedIcon_false + + tr:nth-of-type(odd) + td + background rgba($ShowOddHighlight, $ShowOddHighlightOp) + &.transpOff + background $ShowBgColor2 + + &:hover > + td + background rgba($EpisodeSelectorHoverTran,20%) + + td.transpOff + background $EpisodeSelectorHover diff --git a/src/app/styl/views/videojs.styl b/src/app/styl/views/videojs.styl index 0d51dc9cb8..8a48815be5 100644 --- a/src/app/styl/views/videojs.styl +++ b/src/app/styl/views/videojs.styl @@ -1,871 +1,776 @@ -.vjs-popcorn-skin { - color: #1c1c1c; - .vjs-slider { - position: relative; - cursor: pointer; - background-color: rgba(255,255,255,0.2); - &:hover { - & > .vjs-slider-handle:before { - color: $PlayerColor; - } - } - } - .vjs-slider-handle { - position: absolute; - top: -6px; - width: 14px; - height: 14px; - margin-left: -8px; - &:before { - color: rgba(255,255,255,0); - content: '\25CF'; - font-size: 46px; - line-height: 14px; - transition: all .1s !important; - } - } - - .vjs-control-bar, .vjs-control-window { - display: none; - position: absolute; - bottom: 0; - left: 0; - background: linear-gradient(transparent, rgba(0,0,0,0.7)); - } - - .vjs-control-bar { - right: 0; - height: 60px; - width: 100%; - } - - &.vjs-user-active { - .player-header-background { - display: block; - } - } - .vjs-live-controls { - display: none; - } - &.vjs-has-started { - &.vjs-user-inactive { - &.vjs-playing { - .vjs-control-bar, .vjs-control-window { - display: block; - visibility: hidden; - opacity: 0; - transition: visibility 1s, opacity 1s; - transition: visibility 1s, opacity 1s; - } - } - } - .vjs-big-play-button { - display: none; - } - } - &.vjs-controls-disabled { - .vjs-control-bar, .vjs-control-window { - display: none; - } - .vjs-big-play-button { - display: none; - } - } - &.vjs-using-native-controls { - .vjs-control-bar, .vjs-control-window { - display: none; - } - .vjs-big-play-button { - display: none; - } - } - &.vjs-error { - .vjs-control-bar, .vjs-control-window { - display: none; - } - .player-header-background { - &.vjs-control-bar, .vjs-control-window { - visibility: visible!important; - opacity: 1!important; - display: block!important; - } - } - } - .vjs-control { - outline: none; - position: relative; - float: left; - text-align: center; - margin: 0; - &:focus { - } - } - .vjs-control-text { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; - } - .vjs-play-control { - top: 24px; - cursor: pointer; - width: 14px; - height: 16px; - margin-left: 20px; - &:hover { - transition: all .5s; - -webkit-filter: brightness(0.70); - &:before { - text-shadow: none !important; - } - } - &:before { - position: relative; - text-shadow: none !important; - content: "\f04b"; - color: white; - font-family: "Font Awesome 6 Free"; - font-size: 14px; - line-height: 17px; - font-weight: 900; - } - } - &.vjs-playing { - .vjs-play-control { - &:before { - content: "\f04c"; - } - } - } - .vjs-playback-rate { - .vjs-playback-rate-value { - font-size: 1.5em; - line-height: 2; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - text-align: center; - text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); - } - &.vjs-menu-button { - .vjs-menu { - .vjs-menu-content { - width: 4em; - left: -2em; - list-style: none; - } - } - } - } - .vjs-mute-control { - &:hover { - transition: all .5s; - -webkit-filter: brightness(0.70); - } - } - .vjs-volume-control { - top: 29px; - width: 54px; - float: right; - margin-right: 0px; - overflow: hidden; - height: 6px; - border-radius: 3px/2px; - &:hover { - top: 28px; - height: 8px; - & > .vjs-volume-bar { - height: 8px; - } - } - } - .vjs-volume-bar { - top: 0px; - left: -7px; - height: 6px; - width: 69px; - margin-right: 0px; - border-radius: 3px / 2px; - &:hover { - & > .vjs-volume-level { - height: 8px; - } - & > .vjs-volume-handle:before { - font-size: 14px; - color: rgba(0, 0, 0, 0); - } - } - } - .vjs-volume-menu-button { - .vjs-menu-content { - height: 2.9em; - } - } - .vjs-volume-level { - position: absolute; - top: 0; - left: 0; - height: 6px; - background-color: $PlayerColor; - border-radius: 3px / 2px; - border-radius: 3px / 2px; - background-clip: padding; - background-clip: padding-box; - } - .vjs-volume-handle { - &:before { - color: rgba(0, 0, 0, 0); - content: '\25CF'; - font-size: 14px; - line-height: 17px; - margin-left: 10px; - } - } - .vjs-progress-control { - position: absolute; - top: 19px; - width: auto; - height: 18px; - border-radius: 3px / 2px; - border-radius: 3px / 2px; - background-clip: padding-box; - background-clip: padding-box; - left: 190px; - right: 250px; - padding-top: 10px; - padding-bottom: 2px; - cursor: pointer; - transition: all .1s !important; - &:hover { - height: 20px; - top: 18px; - & > .vjs-progress-holder > .vjs-seek-handle:before { - color: $PlayerColor; - } - } - } - &:hover { - .vjs-progress-control { - border-radius: 3px / 2px; - background-clip: padding; - background-clip: padding-box; - } - } - .vjs-progress-holder { - height: calc(100% + 12px); - top: -10px; - border-radius: 3px/12px 12px 4px 4px; - border-top: 10px solid rgba(0,0,0,0); - border-bottom: 2px solid rgba(0,0,0,0); - background-clip: padding; - background-clip: padding-box; - } - .vjs-play-progress { - background-color: $PlayerColor; - transition: all 0.5s ease; - } - @keyframes progress { - to { background-position: -30px 0; } - } - .vjs-load-progress { - border-radius: 3px / 2px; - border-radius: 3px / 2px; - background-clip: padding-box; - background-clip: padding-box; - background-size: 6px 6px; - transition: width 2s; - animation: progress 2.8s linear infinite; - background-repeat: repeat-x; - background-color: white; - opacity: 0.4; - } - .vjs-seek-handle { - width: 11px; - height: 11px; - transition: all 0.5s ease; - &:before { - padding-top: 0.1em; - } - } - .vjs-time-controls { - position: relative; - color: #fff; - font-family: "Open Sans", sans-serif; - font-size: 16px; - top: 24px; - } - .vjs-current-time { - position: relative; - float: left; - margin-left: 18px; - } - .vjs-duration { - position: relative; - float: left; - } - .vjs-remaining-time { - display: none; - float: left; - } - .vjs-fullscreen-control { - position: relative; - top: 23px; - margin-right: 17px; - margin-left: 17px; - cursor: pointer; - float: right; - width: 18px; - height: 18px; - &:hover { - transition: all .5s; - -webkit-filter: brightness(0.70); - &:before { - text-shadow: none !important; - } - } - &:before { - content: "\f065"; - text-shadow: none !important; - font-size: 18px; - font-family: "Font Awesome 6 Free"; - height: 18px; - width: 18px; - color: white; - font-weight: 900; - } - } - &.vjs-fullscreen { - .vjs-fullscreen-control { - &:before { - content: "\f066"; - } - } - } - .vjs-big-play-button { - left: 0.5em; - top: 0.5em; - font-size: 3em; - display: block; - z-index: 2; - position: absolute; - width: 4em; - height: 2.6em; - text-align: center; - vertical-align: middle; - cursor: pointer; - opacity: 1; - background-color: #07141e; - background-color: rgba(7, 20, 30, 0.7); - border: 0.1em solid #3b4249; - border-radius: 0.8em; - box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25); - transition: all 0.4s; - &:before { - content: "\e001"; - font-family: VideoJS; - line-height: 2.6em; - text-shadow: 0.05em 0.05em 0.1em #000; - text-align: center; - position: absolute; - left: 0; - width: 100%; - height: 100%; - } - } - &.vjs-big-play-centered { - .vjs-big-play-button { - left: 50%; - margin-left: -2.1em; - top: 50%; - margin-top: -1.4000000000000001em; - } - } - .vjs-loading-spinner { - &:before { - content: "\e01e"; - font-family: VideoJS; - position: absolute; - top: 0; - left: 0; - width: 1em; - height: 1em; - text-align: center; - text-shadow: 0em 0em 0.1em $PlayerColor; - color: $PlayerColor; - } - } - .vjs-menu-button { - outline: 0; - position: relative; - float: right; - cursor: pointer; - margin-right: 14px; - height: 18px; - width: 19px; - .vjs-menu { - .vjs-menu-content { - display: block; - padding: 0; - margin: 0; - outline: 0; - position: absolute; - width: 125px; - bottom: 26px; - color: #fff; - max-height: 255px; - overflow: auto; - left: -50px; - background-color: #151517; - opacity: .8; - &::-webkit-scrollbar { - width: 5px; - } - &::-webkit-scrollbar-track { - background-color: #30333c; - border-radius: 2px; - } - &::-webkit-scrollbar-thumb { - background-color: #83888c; - border-radius: 2px; - &:hover { - background-color: #93989c; - } - } - } - } - &:hover { - .vjs-menu { - display: block; - outline: 0; - } - } - ul { - li { - list-style: none; - margin: 0; - padding: 0.3em 0 0.3em 0; - line-height: 1.4em; - font-size: 1.2em; - text-align: center; - outline: 0; - &.vjs-selected { - color: $PlayerColor; - background-color: #151517; - outline: 0; - } - &.vjs-menu-title { - text-align: center; - text-transform: uppercase; - font-size: 1em; - line-height: 2em; - padding: 0; - margin: 0 0 0.3em 0; - font-weight: bold; - cursor: default; - } - } - } - } - .vjs-menu { - display: none; - position: absolute; - bottom: 0; - right: 1px; - width: 20px; - height: 30px; - margin-bottom: 10px; - outline: 0; - } - .vjs_smallersub_button { - &.vjs-control { - outline: 0; - position: relative; - float: right; - cursor: pointer; - margin-right: 14px; - height: 13px; - width: 14px; - &:hover { - transition: all .5s; - -webkit-filter: brightness(0.70); - &:before { - text-shadow: none; - } - } - &:before { - height: 13px; - width: 14px; - font-size: 14px; - line-height: 16px; - content: "A"; - color: #fff; - } - } - } - .vjs_biggersub_button { - &.vjs-control { - outline: 0; - position: relative; - float: right; - cursor: pointer; - margin-right: 14px; - height: 13px; - width: 14px; - &:hover { - transition: all .5s; - -webkit-filter: brightness(0.70); - &:before { - text-shadow: none; - } - } - &:before { - height: 13px; - width: 14px; - font-size: 18px; - line-height: 14px; - content: "A"; - color: #fff; - } - } - } - .vjs-subtitles-button { - &:before { - content: url('../images/icons/Player/Subtitles.png'); - } - &:hover { - &:before { - transition: all .5s; - -webkit-filter: brightness(0.70); - } - } - } - .vjs-hidden { - display: none; - } -} - - - .vjs-popcorn-skin { - &.vjs-has-started { - .vjs-control-bar, .vjs-control-window { - display: block; - visibility: visible; - transition: visibility 0.1s, opacity 0.1s; - transition: visibility 0.1s, opacity 0.1s; - } - } - } - +.vjs-popcorn-skin + color #1c1c1c + .vjs-slider + position relative + cursor pointer + background-color rgba(255,255,255,0.2) + &:hover + & > .vjs-slider-handle:before + color $PlayerColor + + .vjs-slider-handle + position absolute + top -6px + width 14px + height 14px + margin-left -8px + &:before + color rgba(255,255,255,0) + content '\25CF' + font-size 46px + line-height 14px + transition all .1s !important + + .vjs-control-bar, .vjs-control-window + display none + position absolute + bottom 0 + left 0 + background linear-gradient(transparent, rgba(0,0,0,0.7)) + + .vjs-control-bar + right 0 + height 60px + width 100% + + &.vjs-user-active + .player-header-background + display block + + .vjs-live-controls + display none + + &.vjs-has-started + &.vjs-user-inactive + &.vjs-playing + .vjs-control-bar, .vjs-control-window + display block + visibility hidden + opacity 0 + transition visibility 1s, opacity 1s + transition visibility 1s, opacity 1s + + .vjs-big-play-button + display none + + &.vjs-controls-disabled + .vjs-control-bar, .vjs-control-window + display none + + .vjs-big-play-button + display none + + &.vjs-using-native-controls + .vjs-control-bar, .vjs-control-window + display none + + .vjs-big-play-button + display none + + &.vjs-error + .vjs-control-bar, .vjs-control-window + display none + + .player-header-background + &.vjs-control-bar, .vjs-control-window + visibility visible!important + opacity 1!important + display block!important + + .vjs-control + outline none + position relative + float left + text-align center + margin 0 + + .vjs-control-text + border 0 + clip rect(0 0 0 0) + height 1px + margin -1px + overflow hidden + padding 0 + position absolute + width 1px + + .vjs-play-control + top 24px + cursor pointer + width 14px + height 16px + margin-left 20px + &:hover + transition all .5s + -webkit-filter brightness(0.70) + &:before + text-shadow none !important + + &:before + position relative + text-shadow none !important + content "\f04b" + color white + font-family "Font Awesome 6 Free" + font-size 14px + line-height 17px + font-weight 900 + + &.vjs-playing + .vjs-play-control + &:before + content "\f04c" + + .vjs-playback-rate + .vjs-playback-rate-value + font-size 1.5em + line-height 2 + position absolute + top 0 + left 0 + width 100% + height 100% + text-align center + text-shadow 1px 1px 1px rgba(0, 0, 0, 0.5) + + &.vjs-menu-button + .vjs-menu + .vjs-menu-content + width 4em + left -2em + list-style none + + .vjs-mute-control + &:hover + transition all .5s + -webkit-filter brightness(0.70) + + .vjs-volume-control + top 29px + width 54px + float right + margin-right 0px + overflow hidden + height 6px + border-radius 3px/2px + &:hover + top 28px + height 8px + & > .vjs-volume-bar + height 8px + + .vjs-volume-bar + top 0px + left -7px + height 6px + width 69px + margin-right 0px + border-radius 3px / 2px + &:hover + & > .vjs-volume-level + height 8px + + & > .vjs-volume-handle:before + font-size 14px + color rgba(0, 0, 0, 0) + + .vjs-volume-menu-button + .vjs-menu-content + height 2.9em + + .vjs-volume-level + position absolute + top 0 + left 0 + height 6px + background-color $PlayerColor + border-radius 3px / 2px + border-radius 3px / 2px + background-clip padding + background-clip padding-box + + .vjs-volume-handle + &:before + color rgba(0, 0, 0, 0) + content '\25CF' + font-size 14px + line-height 17px + margin-left 10px + + .vjs-progress-control + position absolute + top 19px + width auto + height 18px + border-radius 3px / 2px + border-radius 3px / 2px + background-clip padding-box + background-clip padding-box + left 190px + right 250px + padding-top 10px + padding-bottom 2px + cursor pointer + transition all .1s !important + &:hover + height 20px + top 18px + & > .vjs-progress-holder > .vjs-seek-handle:before + color $PlayerColor + + &:hover + .vjs-progress-control + border-radius 3px / 2px + background-clip padding + background-clip padding-box + + .vjs-progress-holder + height calc(100% + 12px) + top -10px + border-radius 3px/12px 12px 4px 4px + border-top 10px solid rgba(0,0,0,0) + border-bottom 2px solid rgba(0,0,0,0) + background-clip padding + background-clip padding-box + + .vjs-play-progress + background-color $PlayerColor + transition all 0.5s ease + + @keyframes progress + to + background-position -30px 0 + + .vjs-load-progress + border-radius 3px / 2px + border-radius 3px / 2px + background-clip padding-box + background-clip padding-box + background-size 6px 6px + transition width 2s + animation progress 2.8s linear infinite + background-repeat repeat-x + background-color white + opacity 0.4 + + .vjs-seek-handle + width 11px + height 11px + transition all 0.5s ease + &:before + padding-top 0.1em + + .vjs-time-controls + position relative + color #fff + font-family "Open Sans", sans-serif + font-size 16px + top 24px + + .vjs-current-time + position relative + float left + margin-left 18px + + .vjs-duration + position relative + float left + + .vjs-remaining-time + display none + float left + + .vjs-fullscreen-control + position relative + top 23px + margin-right 17px + margin-left 17px + cursor pointer + float right + width 18px + height 18px + &:hover + transition all .5s + -webkit-filter brightness(0.70) + &:before + text-shadow none !important + + &:before + content "\f065" + text-shadow none !important + font-size 18px + font-family "Font Awesome 6 Free" + height 18px + width 18px + color white + font-weight 900 + + &.vjs-fullscreen + .vjs-fullscreen-control + &:before + content "\f066" + + .vjs-big-play-button + left 0.5em + top 0.5em + font-size 3em + display block + z-index 2 + position absolute + width 4em + height 2.6em + text-align center + vertical-align middle + cursor pointer + opacity 1 + background-color #07141e + background-color rgba(7, 20, 30, 0.7) + border 0.1em solid #3b4249 + border-radius 0.8em + box-shadow 0px 0px 1em rgba(255, 255, 255, 0.25) + transition all 0.4s + &:before + content "\e001" + font-family VideoJS + line-height 2.6em + text-shadow 0.05em 0.05em 0.1em #000 + text-align center + position absolute + left 0 + width 100% + height 100% + + &.vjs-big-play-centered + .vjs-big-play-button + left 50% + margin-left -2.1em + top 50% + margin-top -1.4000000000000001em + + .vjs-loading-spinner + &:before + content "\e01e" + font-family VideoJS + position absolute + top 0 + left 0 + width 1em + height 1em + text-align center + text-shadow 0em 0em 0.1em $PlayerColor + color $PlayerColor + + .vjs-menu-button + outline 0 + position relative + float right + cursor pointer + margin-right 14px + height 18px + width 19px + .vjs-menu + .vjs-menu-content + display block + padding 0 + margin 0 + outline 0 + position absolute + width 135px + bottom 26px + color #fff + max-height 355px + overflow auto + left -55px + background-color #151517 + opacity .8 + border-radius 3px + &::-webkit-scrollbar + width 5px + + &::-webkit-scrollbar-track + background-color #30333c + border-radius 2px + + &::-webkit-scrollbar-thumb + background-color #83888c + border-radius 2px + &:hover + background-color #93989c + + &:hover + .vjs-menu + display block + outline 0 + + ul + li + list-style none + margin 0 + padding 0.4em 0 0.4em 0 + line-height 1.4em + font-size 1.2em + text-align center + outline 0 + &.vjs-selected + color $PlayerColor + background-color #151517 + outline 0 + + &.vjs-menu-title + text-align center + text-transform uppercase + font-size 1em + line-height 2em + padding 0 + margin 0 0 0.3em 0 + font-weight bold + cursor default + + .vjs-menu + display none + position absolute + bottom 0 + right 1px + width 20px + height 30px + margin-bottom 10px + outline 0 + + .vjs_smallersub_button + &.vjs-control + outline 0 + position relative + float right + cursor pointer + margin-right 14px + height 13px + width 14px + &:hover + transition all .5s + -webkit-filter brightness(0.70) + &:before + text-shadow none + + &:before + height 13px + width 14px + font-size 14px + line-height 16px + content "A" + color #fff + + .vjs_biggersub_button + &.vjs-control + outline 0 + position relative + float right + cursor pointer + margin-right 14px + height 13px + width 14px + &:hover + transition all .5s + -webkit-filter brightness(0.70) + &:before + text-shadow none + + &:before + height 13px + width 14px + font-size 18px + line-height 14px + content "A" + color #fff + + .vjs-subtitles-button + &:before + content url('../images/icons/player/Subtitles.png') + + &:hover + &:before + transition all .5s + -webkit-filter brightness(0.70) + + .vjs-hidden + display none + +.vjs-popcorn-skin + &.vjs-has-started + .vjs-control-bar, .vjs-control-window + display block + visibility visible + transition visibility 0.1s, opacity 0.1s + transition visibility 0.1s, opacity 0.1s .vjs-popcorn-skin .vjs-control:focus:before, -.vjs-popcorn-skin .vjs-control:hover:before { - text-shadow: 0em 0em 1em #ffffff; -} +.vjs-popcorn-skin .vjs-control:hover:before + text-shadow 0em 0em 1em #ffffff .vjs-popcorn-skin .vjs-mute-control, -.vjs-popcorn-skin .vjs-volume-menu-button { - top: 25px; - cursor: pointer; - float: right; - height: 16px; - width: 22px; - margin-right: 11px; -} +.vjs-popcorn-skin .vjs-volume-menu-button + top 25px + cursor pointer + float right + height 16px + width 22px + margin-right 11px .vjs-popcorn-skin .vjs-mute-control:before, -.vjs-popcorn-skin .vjs-volume-menu-button:before { - position: relative; - content: url('../images/icons/Player/Sound3.png'); -} +.vjs-popcorn-skin .vjs-volume-menu-button:before + position relative + content url('../images/icons/player/Sound3.png') .vjs-popcorn-skin .vjs-mute-control.vjs-vol-2:before, -.vjs-popcorn-skin .vjs-volume-menu-button.vjs-vol-2:before { - content: url('../images/icons/Player/Sound2.png'); -} +.vjs-popcorn-skin .vjs-volume-menu-button.vjs-vol-2:before + content url('../images/icons/player/Sound2.png') .vjs-popcorn-skin .vjs-mute-control.vjs-vol-1:before, -.vjs-popcorn-skin .vjs-volume-menu-button.vjs-vol-1:before { - content: url('../images/icons/Player/Sound1.png'); -} +.vjs-popcorn-skin .vjs-volume-menu-button.vjs-vol-1:before + content url('../images/icons/player/Sound1.png') .vjs-popcorn-skin .vjs-mute-control.vjs-vol-0:before, -.vjs-popcorn-skin .vjs-volume-menu-button.vjs-vol-0:before { - content: url('../images/icons/Player/Sound0.png'); -} +.vjs-popcorn-skin .vjs-volume-menu-button.vjs-vol-0:before + content url('../images/icons/player/Sound0.png') .vjs-popcorn-skin .vjs-progress-holder .vjs-play-progress, -.vjs-popcorn-skin .vjs-progress-holder .vjs-load-progress { - position: absolute; - display: block; - height: 100%; - margin: 0; - padding: 0; - left: 0; - top: 0; - border-radius: 3px / 2px; - border-radius: 3px / 2px; - background-clip: padding; - background-clip: padding-box; - background-clip: padding-box; -} - -.vjs-current-time-display { - width: 50px; - text-align: right; -} - -.vjs-duration-display { - width: 50px; - text-align: left; -} - -.vjs-time-divider { - position: relative; - color: #fff; - font-family: "Open Sans", sans-serif; - font-size: 16px; - position: relative; - float: left; - margin-left: 4px; - margin-right: 3px; - top: 8px; -} +.vjs-popcorn-skin .vjs-progress-holder .vjs-load-progress + position absolute + display block + height 100% + margin 0 + padding 0 + left 0 + top 0 + border-radius 3px / 2px + border-radius 3px / 2px + background-clip padding + background-clip padding-box + background-clip padding-box + +.vjs-current-time-display + width 50px + text-align right + +.vjs-duration-display + width 50px + text-align left + +.vjs-time-divider + position relative + color #fff + font-family "Open Sans", sans-serif + font-size 16px + position relative + float left + margin-left 4px + margin-right 3px + top 8px .vjs-popcorn-skin:hover .vjs-big-play-button, -.vjs-popcorn-skin .vjs-big-play-button:focus { - outline: 0; - border-color: #fff; - background-color: #505050; - background-color: rgba(50, 50, 50, 0.75); - box-shadow: 0 0 3em #ffffff; - box-shadow: 0 0 3em #ffffff; - transition: all 0s; - transition: all 0s; -} - -.vjs-error { - .vjs-big-play-button { - display: none; - } - .vjs-error-display { - display: block; - position: absolute; - left: 0; - top: 75px; - width: 100%; - height: calc(100% - 115px); - } -} - -.vjs-error-display { - display: none; - div { - top: 40%; - color: #666; - position: absolute; - font-size: 1.6em; - text-align: center; - bottom: 1em; - right: 1em; - left: 1em; - width: 60%; - margin-left: 20%; - } -} +.vjs-popcorn-skin .vjs-big-play-button:focus + outline 0 + border-color #fff + background-color #505050 + background-color rgba(50, 50, 50, 0.75) + box-shadow 0 0 3em #ffffff + box-shadow 0 0 3em #ffffff + transition all 0s + transition all 0s + +.vjs-error + .vjs-big-play-button + display none + + .vjs-error-display + display block + position absolute + left 0 + top 75px + width 100% + height calc(100% - 115px) + +.vjs-error-display + display none + div + top 40% + color #666 + position absolute + font-size 1.6em + text-align center + bottom 1em + right 1em + left 1em + width 60% + margin-left 20% .vjs-error-display a, -.vjs-error-display a:visited { - color: #F4A460; -} - -.vjs-loading-spinner { - display: none; - position: absolute; - top: 50%; - left: 50%; - font-size: 4em; - line-height: 1; - width: 1em; - height: 1em; - margin-left: -0.5em; - margin-top: -0.5em; - opacity: 0.75; - animation: spin 1.5s infinite linear; -} - -.video-js { - background-color: #000; - position: relative; - padding: 0; - font-size: 10px; - vertical-align: middle; - font-weight: normal; - font-style: normal; - font-family: Arial, sans-serif; - user-select: none; - user-select: none; - &.vjs-error { - .vjs-loading-spinner { - display: none !important; - } - .vjs-text-track { - display: none!important; - } - } - .vjs-tech { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - } - &.vjs-fullscreen { - position: fixed; - overflow: hidden; - z-index: 1000; - left: 0; - top: 0; - bottom: 0; - right: 0; - width: 100% !important; - height: 100% !important; - &.vjs-user-inactive { - cursor: none; - } - } - &:-webkit-full-screen { - width: 100% !important; - height: 100% !important; - } - &.vjs-using-native-controls { - .vjs-poster { - display: none; - } - } - .vjs-text-track-display { - text-align: center; - position: absolute; - bottom: 38px; - left: 1em; - right: 1em; - } - .vjs-text-track { - display: none; - text-align: center; - background-color: transparent; - text-shadow: 0px 0px 10px #000, -2px -2px 1px #000, 2px -2px 1px #000, -2px 2px 1px #000, 2px 2px 1px #000; - pointer-events: none; - } - .vjs-subtitles { - color: #ffffff; - } - .vjs-captions { - color: #ffcc66; - } -} +.vjs-error-display a:visited + color #F4A460 + +.vjs-loading-spinner + display none + position absolute + top 50% + left 50% + font-size 4em + line-height 1 + width 1em + height 1em + margin-left -0.5em + margin-top -0.5em + opacity 0.75 + animation spin 1.5s infinite linear + +.video-js + background-color #000 + position relative + padding 0 + font-size 10px + vertical-align middle + font-weight normal + font-style normal + font-family Arial, sans-serif + user-select none + user-select none + &.vjs-error + .vjs-loading-spinner + display none !important + + .vjs-text-track + display none!important + + .vjs-tech + position absolute + top -50vh + left -50vh + width calc(100% + 100vh) + height calc(100% + 100vh) + border 50vh solid #000 + + &.vjs-fullscreen + position fixed + overflow hidden + z-index 1000 + left 0 + top 0 + bottom 0 + right 0 + width 100% !important + height 100% !important + &.vjs-user-inactive + cursor none + + &:-webkit-full-screen + width 100% !important + height 100% !important + + &.vjs-using-native-controls + .vjs-poster + display none + + .vjs-text-track-display + text-align center + position absolute + bottom 38px + left 1em + right 1em + + .vjs-text-track + display none + text-align center + background-color transparent + text-shadow 0px 0px 10px #000, -2px -2px 1px #000, 2px -2px 1px #000, -2px 2px 1px #000, 2px 2px 1px #000 + pointer-events none + + .vjs-subtitles + color #ffffff + + .vjs-captions + color #ffcc66 .vjs-popcorn-skin .vjs-menu-button .vjs-menu .vjs-menu-content::-webkit-resizer, .vjs-popcorn-skin .vjs-menu-button .vjs-menu .vjs-menu-content::-webkit-scrollbar-corner, .vjs-popcorn-skin .vjs-menu-button .vjs-menu .vjs-menu-content::-webkit-scrollbar-button, -.vjs-popcorn-skin .vjs-menu-button .vjs-menu .vjs-menu-content::-webkit-scrollbar-track-piece { - display: none; -} +.vjs-popcorn-skin .vjs-menu-button .vjs-menu .vjs-menu-content::-webkit-scrollbar-track-piece + display none .vjs-popcorn-skin .vjs-menu-button ul li:hover, .vjs-popcorn-skin .vjs-menu-button ul li.vjs-selected:focus, -.vjs-popcorn-skin .vjs-menu-button ul li.vjs-selected:hover { - color: $PlayerColor; -} +.vjs-popcorn-skin .vjs-menu-button ul li.vjs-selected:hover + color $PlayerColor .vjs-popcorn-skin .vjs-captions-button:focus .vjs-control-content:before, -.vjs-popcorn-skin .vjs-captions-button:hover .vjs-control-content:before { - box-shadow: 0 0 1em #ffffff; - box-shadow: 0 0 1em #ffffff; -} - -body { - &.vjs-full-window { - padding: 0; - margin: 0; - height: 100%; - overflow-y: auto; - } -} - -.vjs-poster { - background-repeat: no-repeat; - background-position: 50% 50%; - background-size: contain; - cursor: pointer; - height: 100%; - margin: 0; - padding: 0; - position: relative; - width: 100%; - img { - display: block; - margin: 0 auto; - max-height: 100%; - padding: 0; - width: 100%; - } -} - -.vjs-tt-cue { - display: block; - padding: 5px 10px; -} - -.vjs-lock-showing { - display: block !important; - opacity: 1; - visibility: visible; -} +.vjs-popcorn-skin .vjs-captions-button:hover .vjs-control-content:before + box-shadow 0 0 1em #ffffff + box-shadow 0 0 1em #ffffff + +body + &.vjs-full-window + padding 0 + margin 0 + height 100% + overflow-y auto + +.vjs-poster + background-repeat no-repeat + background-position 50% 50% + background-size contain + cursor pointer + height 100% + margin 0 + padding 0 + position relative + width 100% + img + display block + margin 0 auto + max-height 100% + padding 0 + width 100% + +.vjs-tt-cue + display block + padding 5px 10px + +.vjs-lock-showing + display block !important + opacity 1 + visibility visible .vjs-poster, .vjs-loading-spinner, .vjs-big-play-button, .vjs-text-track-display, -.vjs-youtube .iframeblocker { - pointer-events: none !important; -} - -#vjs-tip { - visibility: hidden; - display: block; - padding: 5px; - font-size: 11px; - position: absolute; - z-index: 100000; - pointer-events: none; -} - -#vjs-tip-arrow { - background: url(unquote('data:image/gif;base64,R0lGODlhCQAJAIABAAAAAAAAACH5BAEAAAEALAAAAAAJAAkAAAIRjAOnwIrcDJxvwkplPtchVQAAOw==')) no-repeat top left; - bottom: 0; - left: 50%; - margin-left: -4px; - background-position: bottom left; - position: absolute; - width: 9px; - height: 5px; - opacity: 0; -} - -#vjs-tip-inner { - border-radius: 3px; - border-radius: 3px; - padding: 5px 8px 4px; - background-color: rgba(0,0,0,0); - color: #fff; - max-width: 200px; - text-align: center; - font-size: 150%; - font-weight: 500; -} +.vjs-youtube .iframeblocker + pointer-events none !important + +#vjs-tip + visibility hidden + display block + padding 5px + font-size 11px + position absolute + z-index 100000 + pointer-events none + +#vjs-tip-arrow + background url(unquote('data:image/gif;base64,R0lGODlhCQAJAIABAAAAAAAAACH5BAEAAAEALAAAAAAJAAkAAAIRjAOnwIrcDJxvwkplPtchVQAAOw==')) no-repeat top left + bottom 0 + left 50% + margin-left -4px + background-position bottom left + position absolute + width 9px + height 5px + opacity 0 + +#vjs-tip-inner + border-radius 3px + border-radius 3px + padding 5px 8px 4px + background-color rgba(0,0,0,0) + color #fff + max-width 200px + text-align center + font-size 150% + font-weight 500 diff --git a/src/app/styl/views/vpn.styl b/src/app/styl/views/vpn.styl deleted file mode 100644 index 72eee1b9e1..0000000000 --- a/src/app/styl/views/vpn.styl +++ /dev/null @@ -1,240 +0,0 @@ -.vpn-container - z-index 1 - height 100% - width 100% - position fixed - background-color $BgColor1 - -webkit-user-select none - opacity 1 - background-image url('../images/bg-header.jpg') - background-size cover - background-position 50% 50% - - input[type="text"], input[type="password"] - width: 60% - font-size: 20px - text-align left - text-align-last left - padding-left: 10px; - margin: 10px; - height 30px - border 0 !important - line-height 15px - background-color $InputBoxBg - resize none - color $InputBoxText - font-family $Font, $AlternateFont - cursor text - outline 0 !important - - .margintop - height calc(20% - 20px) - - .create-account - margin-top 2em - - .hidden - display: none - - .account_alert - margin-top: 15px - margin-bottom: 15px - - .account_alert_message - padding: 10px - border-radius: $ButtonRadius - background-color: #f44336 - color: $ButtonText - - .install-vpn - margin-top 3em - - .already-customer - font-size: 13px - cursor: pointer - color: #fff - - .signup-button, .select-plan-button - margin-top: 20px - - .spinner - width: 30px; - height: 30px; - - .green - color:#8ce196 !important - font-weight: bold - - .select-plan-container - margin: 0 auto - width: 380px - padding:35px - text-align:center - - .select-plan-container-top - display: flex - justify-content: center - align-items: center - - span - margin: 0 35px - font-size: 14pt - padding-top: 15px - display: inline - color: #fff - - .switch-input - visibility: hidden - - .switch-input + label - display: block - position: relative - cursor: pointer - outline: none - user-select: none - - .switch-container - width: 90px - - .switch-flat + label - padding: 2px - width: 80px - height: 35px - background-color: #dddddd - border-radius: 60px - transition: background 0.4s - - .switch-flat + label:before, - .switch-flat + label:after - display: block - position: absolute - content: "" - - .switch-flat + label:before - top: 2px; - left: 2px; - bottom: 2px; - right: 2px; - background-color: #fff; - border-radius: 60px; - transition: background 0.4s; - - - .switch-flat + label:after - top: 4px - left: 4px - bottom: 4px - width: 35px - background-color: #dddddd - border-radius: 52px - transition: margin 0.4s, background 0.4s - - - .switch-flat:checked + label - background-color: #8ce196 - - .switch-flat:checked + label:after - margin-left: 41px - background-color: #8ce196 - - .price - font-size: 40px; - line-height: 50px; - font-family: Arial; - font-weight: bold; - color: #fff; - margin: 0; - margin-top: 30px; - margin-bottom: 0px; - - .period - display: block - font-size: 13pt; - color: #fefefe; - - .selectPlanButton - width: 90%; - cursor: pointer - margin-top: 40px; - margin-bottom: 5px; - padding: 18px; - background-color: #fff; - color: #8ce196; - border-radius: 50px; - border: 3px solid #8ce196; - cursor: pointer; - font-size: 16pt; - transition: all 0.5s; - - .selectPlanButton:hover - color: white; - background-color: #8ce196; - - .payment-buttons - display: flex - margin-top: 30px - align-items: center; - justify-content: center; - - .button - height: 70px; - line-height: 90px; - - .grey - color: #888 !important - - .button - font-size: 30px - border-radius: $ButtonRadius - background-clip: padding-box - background-color: $ButtonBg - padding: 0 15px - transition: background-color 0.5s - color: $ButtonText - font-family: $MainFont - font-smoothing: antialiased - text-align: center - line-height: 64px - &:hover - cursor: pointer; - color: $ButtonBgActive; - transition: all .5s; - - .icon-title - opacity 0.9 - margin 80px auto 25px auto - height 110px - max-height 110px - display block - - .overlay-content - height 100% - width 100% - position absolute - background rgba(0, 0, 0, 0.4) - z-index -1 - - .content - margin 0 auto - width 80% - height 60% - color #fff - font-weight 100 - font-family $AlternateFont - font-size 17px - text-align center - - .title-big - font-size 2.4em - margin-bottom 1.5em - - .text-vpn - line-height 1.2em - text-align: justify - text-align-last: center - margin 0 auto - max-width 42em - font-size 1em - - br - line-height 2 \ No newline at end of file diff --git a/src/app/styl/views/windows-titlebar.styl b/src/app/styl/views/windows-titlebar.styl deleted file mode 100644 index 149477f464..0000000000 --- a/src/app/styl/views/windows-titlebar.styl +++ /dev/null @@ -1,123 +0,0 @@ -.windows-titlebar { - position: absolute - top: 0 - left: 0 - width: 100% - height: 24px - display: flex - align-items: center - background-color $TitleBarBg - border-top: 1px solid #000 - font-size: 12px - color: $TitleBarText - font-family: $MainFont -} - -.windows-titlebar .events { - top: 0 - left: 50% - margin-left: -78px -} - -.icon { - height 20px - width 20px - margin-left auto - margin-top 5px -} - -.windows-titlebar-title { - top: initial !important - padding-left: 12px !important - padding-top: 5px - font-size: 14px !important - color: inherit !important - text-shadow: black 0 0 0 - width: auto - margin-right: -64px - opacity: 0.97 -} - -.window-controls { - margin-left: auto - display: flex - align-items: center - -webkit-app-region: no-drag -} - -.window-control { - padding: 0 - height: 24px - width: 30px - cursor: initial !important - opacity: 0.97 -} - -.window-close:hover { - opacity: 1 - background-color: rgba(232, 17, 35, .9) !important -} - -.window-minimize, -.window-maximize { - opacity: 0.87 -} - -.window-minimize:hover, -.window-maximize:hover { - opacity: 1 - background-color: #3a3939 !important -} - -.control-icon { - width: 100%; - height: 100%; -} - -.window-close-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: $TbarIconFilter -} - -.window-close:hover .window-close-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: none -} - -.window-maximize-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: $TbarIconFilter -} - -.window-maximize:hover .window-maximize-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: none -} - -.window-umaximize .window-maximize-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 8.798H8.798V11H0V2.202h2.202V0H11v8.798zm-3.298-5.5h-6.6v6.6h6.6v-6.6zM9.9 1.1H3.298v1.101h5.5v5.5h1.1v-6.6z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: $TbarIconFilter -} - -.window-umaximize:hover .window-maximize-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 8.798H8.798V11H0V2.202h2.202V0H11v8.798zm-3.298-5.5h-6.6v6.6h6.6v-6.6zM9.9 1.1H3.298v1.101h5.5v5.5h1.1v-6.6z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: none -} - -.window-minimize-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: $TbarIconFilter -} - -.window-minimize:hover .window-minimize-icon { - background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% - background-size: 10px - filter: none -} diff --git a/src/app/styl/views/windows_titlebar.styl b/src/app/styl/views/windows_titlebar.styl new file mode 100644 index 0000000000..1c0e898c34 --- /dev/null +++ b/src/app/styl/views/windows_titlebar.styl @@ -0,0 +1,105 @@ +.windows-titlebar + position absolute + top 0 + left 0 + width 100% + height 24px + display flex + align-items center + background-color $TitleBarBg + border-top 1px solid #000 + font-size 12px + color $TitleBarText + font-family $MainFont + +.windows-titlebar .events + top 0 + left 50% + margin-left -78px + +.icon + height 20px + width 20px + margin-left auto + margin-top 5px + +.windows-titlebar-title + top initial !important + padding-left 12px !important + padding-top 5px + font-size 14px !important + color inherit !important + text-shadow black 0 0 0 + width auto + margin-right -64px + opacity 0.97 + +.window-controls + margin-left auto + display flex + align-items center + -webkit-app-region no-drag + +.window-control + padding 0 + height 24px + width 30px + cursor initial !important + opacity 0.97 + +.window-close:hover + opacity 1 + background-color rgba(232, 17, 35, .9) !important + +.window-minimize, +.window-maximize + opacity 0.87 + +.window-minimize:hover, +.window-maximize:hover + opacity 1 + background-color #3a3939 !important + +.control-icon + width 100% + height 100% + +.window-close-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter $TbarIconFilter + +.window-close:hover .window-close-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter none + +.window-maximize-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter $TbarIconFilter + +.window-maximize:hover .window-maximize-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter none + +.window-umaximize .window-maximize-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 8.798H8.798V11H0V2.202h2.202V0H11v8.798zm-3.298-5.5h-6.6v6.6h6.6v-6.6zM9.9 1.1H3.298v1.101h5.5v5.5h1.1v-6.6z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter $TbarIconFilter + +.window-umaximize:hover .window-maximize-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 8.798H8.798V11H0V2.202h2.202V0H11v8.798zm-3.298-5.5h-6.6v6.6h6.6v-6.6zM9.9 1.1H3.298v1.101h5.5v5.5h1.1v-6.6z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter none + +.window-minimize-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter $TbarIconFilter + +.window-minimize:hover .window-minimize-icon + background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' viewBox='0 0 11 11' fill='none'%3E%3Cpath d='M11 4.399V5.5H0V4.399h11z' fill='%23fff'/%3E%3C/svg%3E") no-repeat 50% 50% + background-size 10px + filter none diff --git a/src/app/templates/about.tpl b/src/app/templates/about.tpl index 76fb0cd2a6..1eb24fde8b 100644 --- a/src/app/templates/about.tpl +++ b/src/app/templates/about.tpl @@ -24,10 +24,9 @@
    <% if (Settings.projectUrl) { %><% } %> <% if (Settings.sourceUrl) { %><% } %> - <% if (Settings.projectCi) { %><% } %> - <% if (Settings.projectForum) { %><% } %> - <% if (Settings.projectForum2) { %><% } %> + <% if (Settings.projectForum) { %><% } %> <% if (Settings.projectBlog) { %><% } %> + <% if (Settings.projectBlog) { %><% } %>
    diff --git a/src/app/templates/browser/browser.tpl b/src/app/templates/browser.tpl similarity index 100% rename from src/app/templates/browser/browser.tpl rename to src/app/templates/browser.tpl diff --git a/src/app/templates/file-selector.tpl b/src/app/templates/file-selector.tpl index 5c3823615e..5b3d04ec4a 100644 --- a/src/app/templates/file-selector.tpl +++ b/src/app/templates/file-selector.tpl @@ -1,4 +1,6 @@
    +
    +
    style="opacity:1"<%; break; case 'vlow': %> style="opacity:0.9"<%; break; case 'low': %> style="opacity:0.8"<%; break; case 'high': %> style="opacity:0.6"<%; break; case 'vhigh': %> style="opacity:0.5"<%; break; default: %><%}} if (localFile) { %> style="opacity:1 !important"<%}%>>
    <%=i18n.__('Please select a file to play')%>
    @@ -7,10 +9,10 @@ <% _.each(files, function(file, index) { if (file.display !== false) { %>
  • - <%=file.name %> - <% if (Settings.activateSeedbox) { %> - - <% } else { %><% } %><%=Common.fileSize(file.length) %> + <% if (Settings.activateSeedbox && !localFile) { %> + + <% } else { %><% } %><%=Common.fileSize(file.length) %> + <%=file.name %>
  • <% }}); %> diff --git a/src/app/templates/browser/filter-bar.tpl b/src/app/templates/filter-bar.tpl similarity index 100% rename from src/app/templates/browser/filter-bar.tpl rename to src/app/templates/filter-bar.tpl diff --git a/src/app/templates/help.tpl b/src/app/templates/help.tpl deleted file mode 100644 index 9736dc8e5b..0000000000 --- a/src/app/templates/help.tpl +++ /dev/null @@ -1,50 +0,0 @@ -
    -
    -
    -
    -

    <%= i18n.__("Help Section") %>

    -
    -
    - <%= i18n.__("Did you know?") %> - -
    - -
    -

    <%= i18n.__("What does %s offer?", Settings.projectName ) %>

    -

    <%= i18n.__("With %s, you can watch Movies and TV Series really easily. All you have to do is click on one of the covers, then click 'Watch Now'. But your experience is highly customizable:", Settings.projectName) %> -

      -
    • <%= i18n.__("Movies") %>: <%= i18n.__("Our Movies collection only contains High-Definition movies, available in 720p and 1080p. To watch a movie, simply open %s and navigate through the movies collection, reachable through the 'Movies' tab, in the navigation bar. The default view will show you all movies sorted by popularity, but you can apply your own filters, thanks to the 'Genre' and 'Sort by' filters. Once you have chosen a movie you want to watch, click its cover. Then click 'Watch Now'. Don't forget the popcorn!", Settings.projectName) %>
    • -
    • <%= i18n.__("TV Series") %>: <%= i18n.__("The TV Series tab, that you can reach by clicking 'TV Series' in the navigation bar, will show you all available series in our collection. You can also apply your own filters, same as the Movies, to help you decide what to watch. In this collection, also just click the cover: the new window that will appear will allow you to navigate through Seasons and Episodes. Once your mind is set, just click the 'Watch Now' button.") %>
    • -
    • <%= i18n.__("Choose quality") %>: <%= i18n.__("A slider next to the 'Watch Now' button will let you choose the quality of the stream. You can also set a fixed quality in the Settings tab. Warning: a better quality equals more data to download.") %>
    • -
    • <%= i18n.__("Subtitles") %>: <%= i18n.__("Most of our Movies and TV Series have subtitles in your language. You can set them in the Settings tab. For the Movies, you can even set them through the dropdown menu, in the Movie Details page.") %>
    • -
    • <%= i18n.__("Favorites") %>: <%= i18n.__("Clicking the heart icon on a cover will add the movie/show to your favorites. This collection is reachable through the heart-shaped icon, in the navigation bar. To remove an item from your collection, just click on the icon again! How simple is that?") %>
    • -
    • <%= i18n.__("Watched icon") %>: <%= i18n.__("%s will keep in mind what you've already watched - a little help remembering doesn't cause any harm. You can also set an item as watched by clicking the eye-shaped icon on the covers. You can even build and synchronize your collection with Trakt.tv website, via the Settings tab.", Settings.projectName) %>
    • -
    • <%= i18n.__("Search") %>: <%= i18n.__("In %s, you can use the magnifier icon to open the search. Type a Title, an Actor, a Director or even a Year, press 'Enter' and let us show you what we can offer to fill your needs. To close your current search, you can click on the 'X' located next to your entry or type something else in the field.", Settings.projectName) %>
    • -
    • <%= i18n.__("External Players") %>: <%= i18n.__("If you prefer to use a custom player instead of the built in one, you can do so by clicking the allocated icon on the 'Watch Now' button. A list of your installed players will be shown, select one and %s will send everything to it. If your player isn't on the list, please report it to us.", Settings.projectName) %>
    • -
    • <%= i18n.__("Settings") %>: <%= i18n.__("To push the customization even further, we offer you a large panel of options. To access the Settings, click the wheel-shaped icon in the navigation bar.") %>
    • -
    • <%= i18n.__("Keyboard Navigation") %>: <%= i18n.__("The entire list of keyboard shortcuts is available by pressing '?' on your keyboard, or through the keyboard-shaped icon in the Settings tab.") %>
    • -
    • <%= i18n.__("Custom Torrents and Magnet Links") %>: <%= i18n.__("You can use custom torrents and magnets links in %s. Simply drag and drop .torrent files into the application's window, and/or paste any magnet link.", Settings.projectName) %>
    • -
    • <%= i18n.__("Torrent health") %>: <%= i18n.__("On the details of Movies/TV Series, you can find a little circle, colored in grey, red, yellow or green. Those colors refer to the health of the torrent. A green torrent will be downloaded quickly, while a red torrent may not be downloaded at all, or very slowly. The color grey represents an error in the health calculation for Movies, and needs to be clicked in TV Series in order to display the health.") %>
    • -
    -

    - -

    <%= i18n.__("How does %s work?", Settings.projectName) %>

    -

    <%= i18n.__("%s streams video content through torrents. Our content and metadata are provided by various third-party providers. We don't host any content ourselves.", Settings.projectName) %>
    - <%= i18n.__("Torrent streaming? Well, torrents use Bittorrent protocol, which basically means that you download small parts of the content from another user's computer, while sending the parts you already downloaded to another user. Then, you watch those parts, while the next ones are being downloaded in the background. This exchange allows the content to stay healthy.") %>
    - <%= i18n.__("Once the movie is fully downloaded, you continue to send parts to the other users. And everything is deleted from your computer when you close %s. As simple as that.", Settings.projectName) %>

    - <%= i18n.__("The application itself is built with Node-Webkit, HTML, CSS and Javascript. It works like the Google Chrome browser, except that you host the biggest part of the code on your computer. Yes, %s works on the same technology as a regular website, like... let's say Wikipedia, or Youtube!", Settings.projectName ) %> -

    - -

    <%= i18n.__("I found a bug, how do I report it?") %>

    -

    - <%= i18n.__('You can create an account on our GitHub repository, and click on "Issues".', encodeURI(Settings.issuesUrl)) %> -

  • <%= i18n.__("Use the %s issue filter to search and check if the issue has already been reported or is already fixed.", 'GitHub') %>
  • -
  • <%= i18n.__("Include a screenshot if relevant - Is your issue about a design feature or a bug?") %>
  • -
    -

    <%= i18n.__("A good bug report shouldn't leave others needing to chase you up for more information. Be sure to include the details of your environment.") %>

    -

    * <%= i18n.__("Warning: Always use English when contacting us, or we might not understand you.") %>

    -
    -

    -
    -
    -
    diff --git a/src/app/templates/browser/item.tpl b/src/app/templates/item.tpl similarity index 88% rename from src/app/templates/browser/item.tpl rename to src/app/templates/item.tpl index e787eda0f3..ed88813cb7 100644 --- a/src/app/templates/browser/item.tpl +++ b/src/app/templates/item.tpl @@ -30,7 +30,7 @@
    -

    20){ %> title="<%= title1 %>" data-toggle="tooltip" data-placement="auto bottom" <% } %> ><%= title1 %>

    +

    <%= title1 %>

    <% if (typeof title2 !== 'undefined' && title2 !== '') { %>

    20){ %> title="<%= title2 %>" data-toggle="tooltip" data-placement="auto bottom" <% } %> ><%= title2 %>

    <%} %> diff --git a/src/app/templates/browser/list.tpl b/src/app/templates/list.tpl similarity index 100% rename from src/app/templates/browser/list.tpl rename to src/app/templates/list.tpl diff --git a/src/app/templates/loading.tpl b/src/app/templates/loading.tpl index e40d40082b..ccd273e662 100644 --- a/src/app/templates/loading.tpl +++ b/src/app/templates/loading.tpl @@ -1,6 +1,6 @@
    style="background-image:url( <%= backdrop %> )" <% }catch(err) {} %>>
    -
    +
    style="opacity:<%=Settings.moviesUITransparency%>"<%} else if ($('.sh-backdrop')[0] && Settings.seriesUITransparency !== 'medium') {switch(Settings.seriesUITransparency) { case 'high': %> style="opacity:0.6"<%; break; case 'vhigh': %> style="opacity:0.5"<%; break; default: %><%}}%>>
    ">
    @@ -53,7 +53,7 @@
    -
    +
    <%= i18n.__("Cancel") %>
    diff --git a/src/app/templates/main-window.tpl b/src/app/templates/main-window.tpl index 6428f89bd7..f66b108a50 100644 --- a/src/app/templates/main-window.tpl +++ b/src/app/templates/main-window.tpl @@ -5,7 +5,6 @@
    -
    diff --git a/src/app/templates/movie-detail.tpl b/src/app/templates/movie-detail.tpl index 920ecf4c95..2bc037de96 100644 --- a/src/app/templates/movie-detail.tpl +++ b/src/app/templates/movie-detail.tpl @@ -10,21 +10,21 @@ if (genre) { var genre = [undefined]; }; %> -
    -
    style="opacity:<%=Settings.moviesUITransparency%>"<%}%>>
    - +
    style="opacity:<%=Settings.moviesUITransparency%>"<%}%>>
    +
    +
    +
    +
    +
    +
    -
    -
    -
    <%= displayTitle %>
    -
    <%= year %>
    <%= runtime %> min
    @@ -59,10 +59,8 @@ if (genre) {
    -
    <%= displaySynopsis %>
    -
    diff --git a/src/app/templates/player-chooser.tpl b/src/app/templates/player-chooser.tpl index 98a3d79570..3a2c2dab69 100644 --- a/src/app/templates/player-chooser.tpl +++ b/src/app/templates/player-chooser.tpl @@ -5,7 +5,10 @@