Merge branch 'v2' into nightly
8
.gitignore
vendored
|
@ -19,10 +19,10 @@ cache/*
|
|||
|
||||
# HTTPS Cert/Key #
|
||||
##################
|
||||
*.crt
|
||||
*.key
|
||||
*.csr
|
||||
*.pem
|
||||
/*.crt
|
||||
/*.key
|
||||
/*.csr
|
||||
/*.pem
|
||||
|
||||
# Mergetool
|
||||
*.orgin
|
||||
|
|
124
API.md
|
@ -783,55 +783,53 @@ Optional parameters:
|
|||
|
||||
Returns:
|
||||
json:
|
||||
{"metadata":
|
||||
{"actors": [
|
||||
"Kit Harington",
|
||||
"Emilia Clarke",
|
||||
"Isaac Hempstead-Wright",
|
||||
"Maisie Williams",
|
||||
"Liam Cunningham",
|
||||
],
|
||||
"added_at": "1461572396",
|
||||
"art": "/library/metadata/1219/art/1462175063",
|
||||
"content_rating": "TV-MA",
|
||||
"directors": [
|
||||
"Jeremy Podeswa"
|
||||
],
|
||||
"duration": "2998290",
|
||||
"genres": [
|
||||
"Adventure",
|
||||
"Drama",
|
||||
"Fantasy"
|
||||
],
|
||||
"grandparent_rating_key": "1219",
|
||||
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
||||
"grandparent_title": "Game of Thrones",
|
||||
"guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
|
||||
"labels": [],
|
||||
"last_viewed_at": "1462165717",
|
||||
"library_name": "TV Shows",
|
||||
"media_index": "1",
|
||||
"media_type": "episode",
|
||||
"originally_available_at": "2016-04-24",
|
||||
"parent_media_index": "6",
|
||||
"parent_rating_key": "153036",
|
||||
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
||||
"parent_title": "",
|
||||
"rating": "7.8",
|
||||
"rating_key": "153037",
|
||||
"section_id": "2",
|
||||
"studio": "HBO",
|
||||
"summary": "Jon Snow is dead. Daenerys meets a strong man. Cersei sees her daughter again.",
|
||||
"tagline": "",
|
||||
"thumb": "/library/metadata/153037/thumb/1462175060",
|
||||
"title": "The Red Woman",
|
||||
"updated_at": "1462175060",
|
||||
"writers": [
|
||||
"David Benioff",
|
||||
"D. B. Weiss"
|
||||
],
|
||||
"year": "2016"
|
||||
}
|
||||
{"actors": [
|
||||
"Kit Harington",
|
||||
"Emilia Clarke",
|
||||
"Isaac Hempstead-Wright",
|
||||
"Maisie Williams",
|
||||
"Liam Cunningham",
|
||||
],
|
||||
"added_at": "1461572396",
|
||||
"art": "/library/metadata/1219/art/1462175063",
|
||||
"content_rating": "TV-MA",
|
||||
"directors": [
|
||||
"Jeremy Podeswa"
|
||||
],
|
||||
"duration": "2998290",
|
||||
"genres": [
|
||||
"Adventure",
|
||||
"Drama",
|
||||
"Fantasy"
|
||||
],
|
||||
"grandparent_rating_key": "1219",
|
||||
"grandparent_thumb": "/library/metadata/1219/thumb/1462175063",
|
||||
"grandparent_title": "Game of Thrones",
|
||||
"guid": "com.plexapp.agents.thetvdb://121361/6/1?lang=en",
|
||||
"labels": [],
|
||||
"last_viewed_at": "1462165717",
|
||||
"library_name": "TV Shows",
|
||||
"media_index": "1",
|
||||
"media_type": "episode",
|
||||
"originally_available_at": "2016-04-24",
|
||||
"parent_media_index": "6",
|
||||
"parent_rating_key": "153036",
|
||||
"parent_thumb": "/library/metadata/153036/thumb/1462175062",
|
||||
"parent_title": "",
|
||||
"rating": "7.8",
|
||||
"rating_key": "153037",
|
||||
"section_id": "2",
|
||||
"studio": "HBO",
|
||||
"summary": "Jon Snow is dead. Daenerys meets a strong man. Cersei sees her daughter again.",
|
||||
"tagline": "",
|
||||
"thumb": "/library/metadata/153037/thumb/1462175060",
|
||||
"title": "The Red Woman",
|
||||
"updated_at": "1462175060",
|
||||
"writers": [
|
||||
"David Benioff",
|
||||
"D. B. Weiss"
|
||||
],
|
||||
"year": "2016"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1176,6 +1174,34 @@ Returns:
|
|||
```
|
||||
|
||||
|
||||
### get_pms_update
|
||||
Check for updates to the Plex Media Server.
|
||||
|
||||
```
|
||||
Required parameters:
|
||||
None
|
||||
|
||||
Optional parameters:
|
||||
None
|
||||
|
||||
Returns:
|
||||
json:
|
||||
{"update_available": true,
|
||||
"platform": "Windows",
|
||||
"release_date": "1473721409",
|
||||
"version": "1.1.4.2757-24ffd60",
|
||||
"requirements": "...",
|
||||
"extra_info": "...",
|
||||
"changelog_added": "...",
|
||||
"changelog_fixed": "...",
|
||||
"label": "Download",
|
||||
"distro": "english",
|
||||
"distro_build": "windows-i386",
|
||||
"download_url": "https://downloads.plex.tv/...",
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### get_recently_added
|
||||
Get all items that where recelty added to plex.
|
||||
|
||||
|
|
72
CHANGELOG.md
|
@ -1,5 +1,77 @@
|
|||
# Changelog
|
||||
|
||||
## v2.0.0-beta (2017-12-18)
|
||||
|
||||
* Monitoring:
|
||||
* New: More detailed stream info including subtitles, bitrates, bandwidth, and quality profiles.
|
||||
* New: Terminate sessions from the current activity (Plex Pass only).
|
||||
* Change: Monitoring uses websockets only now.
|
||||
* Notifications:
|
||||
* New: Completely new notification system.
|
||||
* Allow adding multiple of the same notification agent and/or duplicating existing notification agents.
|
||||
* Each notification agent has it's own notification triggers and notification text.
|
||||
* Notification agents are stored in the database instead of the config file. Some notification configurations may have been lost in the transfer. Sorry.
|
||||
* New: Discord notification agent.
|
||||
* New: GroupMe notification agent.
|
||||
* New: MQTT notification agent.
|
||||
* New: More customizable info cards for Discord, Facebook, Hipchat, and Slack.
|
||||
* New: Script notifications are configured individually per script with separate arguments for each notification action.
|
||||
* New: Icon and duration options for Plex Home Theater and XBMC notifications.
|
||||
* New: Notification for Tautulli updates.
|
||||
* New: Added <show>, <season>, <artist>, and <album> notification exclusion tags.
|
||||
* <tv> is renamed to <episode>, and <music> is renamed to <track>
|
||||
* New: Preview notification text in the notifier settings.
|
||||
* New: Properly group recently added notifications when adding a batch of media.
|
||||
* The {season_num}, {episode_num}, and {track_num} parameters will be substituted with the range (e.g. 06-10)
|
||||
* New: Option to group recently added notifications by show/artist or season/album.
|
||||
* New: More detailed media info (video, audio, subtitle, file, etc.) notification options available.
|
||||
* New: Added notification text modifiers to change case and slice lists.
|
||||
* New: Custom notification conditions using parameters to filter notifications.
|
||||
* New: Button to trigger manual recently added notifications from the info pages.
|
||||
* New: Lookup TVMaze and TheMovieDatabase links.
|
||||
* Remove: The shared Imgur client ID has been removed. Please enter your own client ID in the settings to continue uploading posters.
|
||||
* Change: Notifications with a blank subject or body will no longer be sent at all.
|
||||
* Change: Line breaks inserted automatically in Email notification text.
|
||||
* Change: Notifications for season/episodes now use the season poster and album/track now use the album art.
|
||||
* Change: The {action} parameter is no longer capitalized.
|
||||
* Change: Notification success or failure added to notification logs.
|
||||
* API:
|
||||
* New: Added check for Plex Media Server updates with the Tautulli API.
|
||||
* New: Added show/artist and episode/track titles to the "get_history" API command.
|
||||
* New: Added manual trigger for recently added notifications.
|
||||
* Remove: Defunct API v1.
|
||||
* Change: The "notify" API command now requires a notifier_id instead of an agent_id. The notifier ID can be found in the settings for each notification agent.
|
||||
* Change: The returned json for the "get_metadata" API command is no longer nested under the "metadata" key.
|
||||
* UI:
|
||||
* New: Updated current activity, watch statistics, and library statistics cards on the home page.
|
||||
* New: Toggle stats and recently added categories directly on the homepage.
|
||||
* New: Ability to delete synced items from the Synced Items page.
|
||||
* New: Updated platform icons to a uniform style.
|
||||
* Remove: Setting for number of top items for watch statistic cards.
|
||||
* Change: Separate API and websocket logs.
|
||||
* Android Tautulli Remote App (beta):
|
||||
* New: Download the Tautulli Remote app on Google Play!
|
||||
* Link the app using a QR code in the Tautulli settings.
|
||||
* New: Push notifications directly to the Tautulli Remote app.
|
||||
* Other:
|
||||
* New: Option to update Tautulli automatically when an update is available.
|
||||
* New: Option to switch the tracking git remote and branch.
|
||||
* New: Option to change the path to your git environment variable.
|
||||
* New: Option to use a HTTPS certificate chain.
|
||||
* New: Option to override the Plex Web URL for click-through links.
|
||||
* New: Separate watched percentage for movies, episodes, and tracks.
|
||||
* New: Show changelog after updating Tautulli.
|
||||
* New: Support for IPv6 geolocation lookup.
|
||||
* New: Download the Tautulli configuration file or database from the settings.
|
||||
* New: Log failed Tautulli login attempts.
|
||||
* Fix: Modal popups not working on mobile Safari.
|
||||
* Fix: Prevent password managers from autofilling the password in the settings.
|
||||
* Fix: Unable to search with special characters.
|
||||
* Remove: Some unused options have been removed from the settings page.
|
||||
* Change: The database schema has been changed, and reverting back to PlexPy v1 will not work.
|
||||
* Change: The dev branch has been depreciated. A master/beta/nightly system is used instead.
|
||||
|
||||
|
||||
## v1.4.25 (2017-10-02)
|
||||
|
||||
* Fix: Tab instead of spaces preventing startup.
|
||||
|
|
40
PlexPy.py
|
@ -6,20 +6,20 @@
|
|||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This file is part of PlexPy.
|
||||
# This file is part of Tautulli.
|
||||
#
|
||||
# PlexPy is free software: you can redistribute it and/or modify
|
||||
# Tautulli 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.
|
||||
#
|
||||
# PlexPy is distributed in the hope that it will be useful,
|
||||
# Tautulli 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 PlexPy. If not, see <http://www.gnu.org/licenses/>.
|
||||
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -43,11 +43,11 @@ signal.signal(signal.SIGTERM, plexpy.sig_handler)
|
|||
|
||||
def main():
|
||||
"""
|
||||
PlexPy application entry point. Parses arguments, setups encoding and
|
||||
Tautulli application entry point. Parses arguments, setups encoding and
|
||||
initializes the application.
|
||||
"""
|
||||
|
||||
# Fixed paths to PlexPy
|
||||
# Fixed paths to Tautulli
|
||||
if hasattr(sys, 'frozen'):
|
||||
plexpy.FULL_PATH = os.path.abspath(sys.executable)
|
||||
else:
|
||||
|
@ -81,9 +81,9 @@ def main():
|
|||
parser.add_argument(
|
||||
'-d', '--daemon', action='store_true', help='Run as a daemon')
|
||||
parser.add_argument(
|
||||
'-p', '--port', type=int, help='Force PlexPy to run on a specified port')
|
||||
'-p', '--port', type=int, help='Force Tautulli to run on a specified port')
|
||||
parser.add_argument(
|
||||
'--dev', action='store_true', help='Start PlexPy in the development environment')
|
||||
'--dev', action='store_true', help='Start Tautulli in the development environment')
|
||||
parser.add_argument(
|
||||
'--datadir', help='Specify a directory where to store your data files')
|
||||
parser.add_argument(
|
||||
|
@ -93,8 +93,8 @@ def main():
|
|||
parser.add_argument(
|
||||
'--pidfile', help='Create a pid file (only relevant when running as a daemon)')
|
||||
parser.add_argument(
|
||||
'--nofork', action='store_true', help='Start PlexPy as a service, do not fork when restarting')
|
||||
|
||||
'--nofork', action='store_true', help='Start Tautulli as a service, do not fork when restarting')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.verbose:
|
||||
|
@ -108,7 +108,7 @@ def main():
|
|||
|
||||
if args.dev:
|
||||
plexpy.DEV = True
|
||||
logger.debug(u"PlexPy is running in the dev environment.")
|
||||
logger.debug(u"Tautulli is running in the dev environment.")
|
||||
|
||||
if args.daemon:
|
||||
if sys.platform == 'win32':
|
||||
|
@ -120,7 +120,7 @@ def main():
|
|||
|
||||
if args.nofork:
|
||||
plexpy.NOFORK = True
|
||||
logger.info("PlexPy is running as a service, it will not fork when restarted.")
|
||||
logger.info("Tautulli is running as a service, it will not fork when restarted.")
|
||||
|
||||
if args.pidfile:
|
||||
plexpy.PIDFILE = str(args.pidfile)
|
||||
|
@ -195,14 +195,11 @@ def main():
|
|||
plexpy.start()
|
||||
|
||||
# Open connection for websocket
|
||||
if plexpy.CONFIG.MONITORING_USE_WEBSOCKET:
|
||||
try:
|
||||
web_socket.start_thread()
|
||||
except:
|
||||
logger.warn(u"Websocket :: Unable to open connection.")
|
||||
# Fallback to polling
|
||||
plexpy.POLLING_FAILOVER = True
|
||||
plexpy.initialize_scheduler()
|
||||
try:
|
||||
web_socket.start_thread()
|
||||
except:
|
||||
logger.warn(u"Websocket :: Unable to open connection.")
|
||||
plexpy.initialize_scheduler()
|
||||
|
||||
# Force the http port if neccessary
|
||||
if args.port:
|
||||
|
@ -230,6 +227,7 @@ def main():
|
|||
'http_proxy': plexpy.CONFIG.HTTP_PROXY,
|
||||
'enable_https': plexpy.CONFIG.ENABLE_HTTPS,
|
||||
'https_cert': plexpy.CONFIG.HTTPS_CERT,
|
||||
'https_cert_chain': plexpy.CONFIG.HTTPS_CERT_CHAIN,
|
||||
'https_key': plexpy.CONFIG.HTTPS_KEY,
|
||||
'http_username': plexpy.CONFIG.HTTP_USERNAME,
|
||||
'http_password': plexpy.CONFIG.HTTP_PASSWORD,
|
||||
|
@ -256,6 +254,8 @@ def main():
|
|||
plexpy.shutdown()
|
||||
elif plexpy.SIGNAL == 'restart':
|
||||
plexpy.shutdown(restart=True)
|
||||
elif plexpy.SIGNAL == 'checkout':
|
||||
plexpy.shutdown(restart=True, checkout=True)
|
||||
else:
|
||||
plexpy.shutdown(restart=True, update=True)
|
||||
|
||||
|
|
16
README.md
|
@ -1,8 +1,8 @@
|
|||
# PlexPy
|
||||
# Tautulli
|
||||
|
||||
[](https://discord.gg/36ggawe)
|
||||
[](https://gitter.im/plexpy/general)
|
||||
[](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program)
|
||||
[](https://discord.gg/36ggawe)
|
||||
[](https://www.reddit.com/r/Tautulli/)
|
||||
[](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program)
|
||||
|
||||
A python based web application for monitoring, analytics and notifications for [Plex Media Server](https://plex.tv).
|
||||
|
||||
|
@ -27,13 +27,13 @@ This project is based on code from [Headphones](https://github.com/rembo10/headp
|
|||
|
||||
## Preview
|
||||
|
||||
* [Full preview gallery on Imgur](https://imgur.com/a/RwQPM)
|
||||
* [Full preview gallery on our website](http://tautulli.com)
|
||||
|
||||

|
||||

|
||||
|
||||
## Installation and Support
|
||||
|
||||
* [Installation Guides](https://github.com/JonnyWong16/plexpy/wiki/Installation) shows you how to install PlexPy.
|
||||
* [Installation Guides](https://github.com/JonnyWong16/plexpy/wiki/Installation) shows you how to install Tautulli.
|
||||
* [FAQs](https://github.com/JonnyWong16/plexpy/wiki/Frequently-Asked-Questions-(FAQ)) in the wiki can help you with common problems.
|
||||
|
||||
**Support** the project by implementing new features, solving support tickets and provide bug fixes.
|
||||
|
@ -49,7 +49,7 @@ This project is based on code from [Headphones](https://github.com/rembo10/headp
|
|||
- Checking the [Wiki](https://github.com/JonnyWong16/plexpy/wiki) for
|
||||
[ [Installation] ](https://github.com/JonnyWong16/plexpy/wiki/Installation) and
|
||||
[ [FAQs] ](https://github.com/JonnyWong16/plexpy/wiki/Frequently-Asked-Questions-(FAQ)).
|
||||
- For basic questions try asking on [Gitter](https://gitter.im/plexpy/general) or the [Plex Forums](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program) first before opening an issue.
|
||||
- For basic questions try asking on [Discord](https://discord.gg/36ggawe), [Reddit](https://www.reddit.com/r/Tautulli), or the [Plex Forums](https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program) first before opening an issue.
|
||||
|
||||
##### If nothing has worked:
|
||||
|
||||
|
|
|
@ -8,129 +8,40 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>PlexPy - ${title} | ${server_name}</title>
|
||||
<title>Tautulli - ${title} | ${server_name}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link href="${http_root}css/bootstrap3/bootstrap.css" rel="stylesheet">
|
||||
<link href="${http_root}css/pnotify.custom.min.css" rel="stylesheet" />
|
||||
<link href="${http_root}css/plexpy.css" rel="stylesheet">
|
||||
<link href="${http_root}css/plexpy.css${cache_param}" rel="stylesheet">
|
||||
<link href="${http_root}css/opensans.min.css" rel="stylesheet">
|
||||
<link href="${http_root}css/font-awesome.min.css" rel="stylesheet">
|
||||
${next.headIncludes()}
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="${http_root}images/favicon.ico"/>
|
||||
<link rel="shortcut icon" href="${http_root}images/favicon.png">
|
||||
|
||||
<!-- Allow web app to be run in full-screen mode. -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<!-- Configure the status bar. -->
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<!-- Set the viewport. -->
|
||||
<meta name="viewport" content="initial-scale=1">
|
||||
<!-- Disable automatic phone number detection. -->
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<!-- Favicons -->
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="${http_root}images/favicon/favicon-32x32.png?v=2.0.0">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="${http_root}images/favicon/favicon-16x16.png?v=2.0.0">
|
||||
<link rel="shortcut icon" href="${http_root}images/favicon/favicon.ico?v=2.0.0">
|
||||
|
||||
<!-- ICONS -->
|
||||
<!-- IE10 icon -->
|
||||
<meta name="application-name" content="PlexPy" />
|
||||
<meta name="msapplication-config" content="${http_root}xml/IEconfig.xml"/>
|
||||
<!-- Android >M39 icon -->
|
||||
<link rel="manifest" href="${http_root}json/Android-manifest.json">
|
||||
<!-- iPad retina icon -->
|
||||
<link href="${http_root}images/res/ios/icon-76@2x.png" sizes="152x152" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPad retina icon (iOS < 7) -->
|
||||
<link href="${http_root}images/res/ios/icon-72@2x.png" sizes="144x144" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPad non-retina icon -->
|
||||
<link href="${http_root}images/res/ios/icon-76.png" sizes="76x76" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPad non-retina icon (iOS < 7) -->
|
||||
<link href="${http_root}images/res/ios/icon-72.png" sizes="72x72" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPhone 6 Plus icon -->
|
||||
<link href="${http_root}images/res/ios/icon-60@2x.png" sizes="120x120" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPhone retina icon (iOS < 7) -->
|
||||
<link href="${http_root}images/res/ios/icon@2x.png" sizes="114x114" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPhone non-retina icon (iOS < 7) -->
|
||||
<link href="${http_root}images/res/ios/icon.png" sizes="57x57" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPhone / iPod Touch -->
|
||||
<link href="${http_root}images/res/ios/icon-60@3x.png" sizes="180x180" rel="apple-touch-icon-precomposed">
|
||||
<link href="${http_root}images/res/ios/icon-60.png" sizes="60x60" rel="apple-touch-icon-precomposed">
|
||||
<!-- Spotlight Icon -->
|
||||
<link href="${http_root}images/res/ios/icon-40.png" sizes="40x40" rel="apple-touch-icon-precomposed">
|
||||
<link href="${http_root}images/res/ios/icon-40@2x.png" sizes="80x80" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPhone Spotlight and Settings Icon -->
|
||||
<link href="${http_root}images/res/ios/icon-small.png" sizes="29x29" rel="apple-touch-icon-precomposed">
|
||||
<link href="${http_root}images/res/ios/icon-small@2x.png" sizes="58x58" rel="apple-touch-icon-precomposed">
|
||||
<!-- iPad Spotlight and Settings Icon -->
|
||||
<link href="${http_root}images/res/ios/icon-50.png" sizes="50x50" rel="apple-touch-icon-precomposed">
|
||||
<link href="${http_root}images/res/ios/icon-50@2x.png" sizes="100x100" rel="apple-touch-icon-precomposed">
|
||||
|
||||
<!-- STARTUP IMAGES -->
|
||||
<!-- iPad retina portrait startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-Portrait@2x~ipad.png"
|
||||
media="(device-width: 768px) and (device-height: 1024px)
|
||||
and (-webkit-device-pixel-ratio: 2)
|
||||
and (orientation: portrait)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPad retina landscape startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-Landscape@2x~ipad.png"
|
||||
media="(device-width: 768px) and (device-height: 1024px)
|
||||
and (-webkit-device-pixel-ratio: 2)
|
||||
and (orientation: landscape)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPad non-retina portrait startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-Portrait~ipad.png"
|
||||
media="(device-width: 768px) and (device-height: 1024px)
|
||||
and (-webkit-device-pixel-ratio: 1)
|
||||
and (orientation: portrait)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPad non-retina landscape startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-Landscape~ipad.png"
|
||||
media="(device-width: 768px) and (device-height: 1024px)
|
||||
and (-webkit-device-pixel-ratio: 1)
|
||||
and (orientation: landscape)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPhone 6 Plus portrait startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-736h.png"
|
||||
media="(device-width: 414px) and (device-height: 736px)
|
||||
and (-webkit-device-pixel-ratio: 3)
|
||||
and (orientation: portrait)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPhone 6 Plus landscape startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-Landscape-736h.png"
|
||||
media="(device-width: 414px) and (device-height: 736px)
|
||||
and (-webkit-device-pixel-ratio: 3)
|
||||
and (orientation: landscape)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPhone 6 startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-667h.png"
|
||||
media="(device-width: 375px) and (device-height: 667px)
|
||||
and (-webkit-device-pixel-ratio: 2)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPhone 5 startup image -->
|
||||
<link href="${http_root}images/res/ios/Default-568h@2x~iphone5.jpg"
|
||||
media="(device-width: 320px) and (device-height: 568px)
|
||||
and (-webkit-device-pixel-ratio: 2)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPhone < 5 retina startup image -->
|
||||
<link href="${http_root}images/res/ios/Default@2x~iphone.png"
|
||||
media="(device-width: 320px) and (device-height: 480px)
|
||||
and (-webkit-device-pixel-ratio: 2)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<!-- iPhone < 5 non-retina startup image -->
|
||||
<link href="${http_root}images/res/ios/Default~iphone.png"
|
||||
media="(device-width: 320px) and (device-height: 480px)
|
||||
and (-webkit-device-pixel-ratio: 1)"
|
||||
rel="apple-touch-startup-image">
|
||||
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="${http_root}images/favicon/android-chrome-192x192.png?v=2.0.0">
|
||||
<link rel="manifest" href="${http_root}json/Android-manifest.json?v=2.0.0">
|
||||
<meta name="theme-color" content="#1f1f1f">
|
||||
<!-- Apple -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="${http_root}images/favicon/apple-touch-icon.png?v=2.0.0">
|
||||
<link rel="mask-icon" href="${http_root}images/favicon/safari-pinned-tab.svg?v=2.0.0" color="#1f1f1f">
|
||||
<meta name="apple-mobile-web-app-title" content="Tautulli">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="viewport" content="initial-scale=1">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<!-- IE10 icon -->
|
||||
<meta name="application-name" content="Tautulli">
|
||||
<meta name="msapplication-TileColor" content="#1f1f1f">
|
||||
<meta name="msapplication-TileImage" content="${http_root}images/favicon/mstile-144x144.png?v=2.0.0">
|
||||
<meta name="msapplication-config" content="${http_root}xml/IEconfig.xml?v=2.0.0" />
|
||||
</head>
|
||||
|
||||
<body class="content">
|
||||
|
@ -139,7 +50,7 @@
|
|||
% if _session['user_group'] == 'admin':
|
||||
% if plexpy.CONFIG.CHECK_GITHUB and not plexpy.CURRENT_VERSION:
|
||||
<div id="updatebar" style="display: none;">
|
||||
You're running an unknown version of PlexPy.<br />
|
||||
You're running an unknown version of Tautulli.<br />
|
||||
<a href="update">Update</a> or <a href="#" id="updateDismiss">Close</a>
|
||||
</div>
|
||||
% elif plexpy.CONFIG.CHECK_GITHUB and plexpy.CURRENT_VERSION != plexpy.LATEST_VERSION and plexpy.COMMITS_BEHIND > 0 and plexpy.INSTALL_TYPE != 'win':
|
||||
|
@ -161,7 +72,7 @@
|
|||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="home">
|
||||
<img alt="PlexPy" src="${http_root}images/logo-plexpy@2x.png" height="40">
|
||||
<img alt="Tautulli" src="${http_root}images/logo-tautulli-50.png" height="40">
|
||||
</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse navbar-right" id="navbar-collapse-1">
|
||||
|
@ -245,25 +156,14 @@
|
|||
</nav>
|
||||
</div>
|
||||
|
||||
<div id="confirm-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">Confirm</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="confirm-message" style="text-align: center; margin-top: 20px; margin-bottom: 20px;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-button">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${next.headerIncludes()}
|
||||
|
||||
<div class="body-container">
|
||||
${next.body()}
|
||||
</div>
|
||||
|
||||
${next.modalIncludes()}
|
||||
|
||||
% if _session['user_group'] != 'admin':
|
||||
<div id="admin-login-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="admin-login-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
|
@ -310,13 +210,13 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">PlexPy Donation</h4>
|
||||
<h4 class="modal-title">Tautulli Donation</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12" style="text-align: center;">
|
||||
<h4>
|
||||
<strong>Thank you for supporting PlexPy!</strong>
|
||||
<strong>Thank you for supporting Tautulli!</strong>
|
||||
</h4>
|
||||
<p>
|
||||
Please select a donation method.
|
||||
|
@ -336,7 +236,7 @@
|
|||
<p>
|
||||
Click the button below to continue to PayPal.
|
||||
</p>
|
||||
<a href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=6XPPKTDSX9QFL&lc=US&item_name=PlexPy¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted')}" target="_blank">
|
||||
<a href="${anon_url('https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=6XPPKTDSX9QFL&lc=US&item_name=Tautulli¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted')}" target="_blank">
|
||||
<img src="images/gold-rect-paypal-34px.png" alt="PayPal">
|
||||
</a>
|
||||
</div>
|
||||
|
@ -344,7 +244,7 @@
|
|||
<p>
|
||||
Click the button below to continue to Flattr.
|
||||
</p>
|
||||
<a href="${anon_url('https://flattr.com/submit/auto?user_id=JonnyWong16&url=https://github.com/JonnyWong16/plexpy&title=PlexPy&language=en_GB&tags=github&category=software')}" target="_blank">
|
||||
<a href="${anon_url('https://flattr.com/submit/auto?user_id=JonnyWong16&url=https://github.com/JonnyWong16/plexpy&title=Tautulli&language=en_GB&tags=github&category=software')}" target="_blank">
|
||||
<img src="images/flattr-badge-large.png" alt="Flattr">
|
||||
</a>
|
||||
</div>
|
||||
|
@ -364,16 +264,30 @@
|
|||
</div>
|
||||
% endif
|
||||
|
||||
${next.headerIncludes()}
|
||||
<div class="body-container">
|
||||
${next.body()}
|
||||
<div id="confirm-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">Confirm</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="confirm-message" style="text-align: center; margin-top: 20px; margin-bottom: 20px;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-button">Confirm</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="${http_root}js/jquery-2.1.4.min.js"></script>
|
||||
<script src="${http_root}js/bootstrap.min.js"></script>
|
||||
<script src="${http_root}js/bootstrap-hover-dropdown.min.js"></script>
|
||||
<script src="${http_root}js/pnotify.custom.min.js"></script>
|
||||
<script src="${http_root}js/script.js"></script>
|
||||
<script src="${http_root}js/script.js${cache_param}"></script>
|
||||
<script src="${http_root}js/jquery.qrcode.min.js"></script>
|
||||
% if _session['user_group'] == 'admin' and plexpy.CONFIG.BROWSER_ENABLED:
|
||||
<script src="${http_root}js/ajaxNotifications.js"></script>
|
||||
|
@ -392,7 +306,7 @@ ${next.headerIncludes()}
|
|||
}
|
||||
|
||||
$("#nav-shutdown").click(function() {
|
||||
$("#confirm-message").text("Are you sure you want to shutdown PlexPy?");
|
||||
$("#confirm-message").text("Are you sure you want to shutdown Tautulli?");
|
||||
$('#confirm-modal').modal();
|
||||
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||
window.location.href = "shutdown";
|
||||
|
@ -400,7 +314,7 @@ ${next.headerIncludes()}
|
|||
});
|
||||
|
||||
$("#nav-restart").click(function() {
|
||||
$("#confirm-message").text("Are you sure you want to restart PlexPy?");
|
||||
$("#confirm-message").text("Are you sure you want to restart Tautulli?");
|
||||
$('#confirm-modal').modal();
|
||||
$('#confirm-modal').one('click', '#confirm-button', function () {
|
||||
window.location.href = "restart";
|
||||
|
@ -465,6 +379,18 @@ ${next.headerIncludes()}
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Allow stacked bootstrap modals
|
||||
$(document).on('show.bs.modal', '.modal', function (event) {
|
||||
var zIndex = 1040 + (10 * $('.modal:visible').length);
|
||||
$(this).css('z-index', zIndex);
|
||||
setTimeout(function() {
|
||||
$('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
|
||||
}, 0);
|
||||
});
|
||||
$(document).on('hidden.bs.modal', '.modal', function () {
|
||||
$('.modal:visible').length && $(document.body).addClass('modal-open');
|
||||
});
|
||||
});
|
||||
|
||||
% if _session['user_group'] != 'admin':
|
||||
|
@ -477,6 +403,7 @@ ${next.javascriptIncludes()}
|
|||
</body>
|
||||
</html>
|
||||
|
||||
<%def name="modalIncludes()"></%def>
|
||||
<%def name="javascriptIncludes()"></%def>
|
||||
<%def name="headIncludes()"></%def>
|
||||
<%def name="headerIncludes()"></%def>
|
||||
|
|
|
@ -31,15 +31,15 @@ DOCUMENTATION :: END
|
|||
% endif
|
||||
<tr>
|
||||
<td>Configuration File:</td>
|
||||
<td>${plexpy.CONFIG_FILE}</td>
|
||||
<td><a class="no-highlight" href="download_config" data-toggle="tooltip" data-placement="right" title="Download Configuration">${plexpy.CONFIG_FILE}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Database File:</td>
|
||||
<td>${plexpy.DB_FILE}</td>
|
||||
<td><a class="no-highlight" href="download_database" data-toggle="tooltip" data-placement="right" title="Download Database">${plexpy.DB_FILE}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Log File:</td>
|
||||
<td><a class="no-highlight" href="logFile" target="_blank">${os.path.join(plexpy.CONFIG.LOG_DIR, logger.FILENAME)}</a></td>
|
||||
<td><a class="no-highlight" href="download_log" data-toggle="tooltip" data-placement="right" title="Download Log">${os.path.join(plexpy.CONFIG.LOG_DIR, logger.FILENAME)}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Backup Directory:</td>
|
||||
|
@ -77,78 +77,37 @@ DOCUMENTATION :: END
|
|||
<a id="source-link" class="no-highlight" href="${anon_url('https://github.com/%s/plexpy' % plexpy.CONFIG.GIT_USER)}" target="_blank">GitHub Source</a> |
|
||||
<a class="no-highlight guidelines-modal-link" href="${anon_url('https://github.com/%s/plexpy/issues' % plexpy.CONFIG.GIT_USER)}" data-id="issue">GitHub Issues</a> |
|
||||
<a class="no-highlight guidelines-modal-link" href="${anon_url('http://feathub.com/%s/plexpy' % plexpy.CONFIG.GIT_USER)}" data-id="feature request">FeatHub Feature Requests</a> |
|
||||
<a class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki' % plexpy.CONFIG.GIT_USER)}" target="_blank">PlexPy Wiki</a> |
|
||||
<a id="faq-source-link" class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki/Frequently-Asked-Questions-(FAQ)' % plexpy.CONFIG.GIT_USER)}" target="_blank">PlexPy FAQ</a>
|
||||
<a class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki' % plexpy.CONFIG.GIT_USER)}" target="_blank">Tautulli Wiki</a> |
|
||||
<a id="faq-source-link" class="no-highlight" href="${anon_url('https://github.com/%s/plexpy/wiki/Frequently-Asked-Questions-(FAQ)' % plexpy.CONFIG.GIT_USER)}" target="_blank">Tautulli FAQ</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Support:</td>
|
||||
<td>
|
||||
<a class="no-highlight support-modal-link" href="${anon_url('https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program')}" target="_blank">Plex Forums</a> |
|
||||
<a class="no-highlight support-modal-link" href="${anon_url('https://gitter.im/plexpy/general')}" target="_blank">PlexPy Gitter Chat</a> |
|
||||
<a id="best-support-link" class="no-highlight support-modal-link" href="${anon_url('https://discord.gg/011TFFWSuNFI02EKr')}" target="_blank">/r/Plex Discord Server</a> |
|
||||
<a class="no-highlight support-modal-link" href="${anon_url('https://discord.gg/36ggawe')}" target="_blank">PlexPy Discord Server</a>
|
||||
<a class="no-highlight support-modal-link" href="${anon_url('https://discord.gg/36ggawe')}" target="_blank">Tautulli Discord Server</a> |
|
||||
<a class="no-highlight support-modal-link" href="${anon_url('https://www.reddit.com/r/Tautulli')}" target="_blank">Tautulli Subreddit</a> |
|
||||
<a class="no-highlight support-modal-link" href="${anon_url('https://forums.plex.tv/discussion/169591/plexpy-another-plex-monitoring-program')}" target="_blank">Plex Forums</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="guidelines-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="guidelines-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">Guidelines</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div style="text-align: center; margin-top: 20px; margin-bottom: 20px;">
|
||||
<strong>Please read the <a href="#" target="_blank" id="guidelines-link">guidelines</a> in the README document <br />before submitting a new <span id="guidelines-type"></span>!</strong>
|
||||
<br /><br />
|
||||
Your post may be removed for failure to follow the guidelines.
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" target="_blank" id="guidelines-continue" class="btn btn-bright">Continue</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="support-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="support-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">Support</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div style="text-align: center; margin-top: 20px; margin-bottom: 20px;">
|
||||
<strong>Please read the <a href="#" target="_blank" id="faq-link">FAQ</a> before asking for help!</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" target="_blank" id="support-continue" class="btn btn-bright">Continue</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$("#install_geoip_db, #reinstall_geoip_db").click(function () {
|
||||
var msg = 'Are you sure you want to install the GeoLite2 database?<br /><br />' +
|
||||
'The database is used to lookup IP address geolocation info.<br />' +
|
||||
'The database will be downloaded from <a href="${anon_url("https://dev.maxmind.com/geoip/geoip2/geolite2/")}" target="_blank">MaxMind</a>, <br />' +
|
||||
'and requires <strong>100MB</strong> of free space to install in your PlexPy directory.<br />'
|
||||
'and requires <strong>100MB</strong> of free space to install in your Tautulli directory.<br />'
|
||||
var url = 'install_geoip_db';
|
||||
confirmAjaxCall(url, msg, 'Installing GeoLite2 database.', getConfigurationTable);
|
||||
confirmAjaxCall(url, msg, null, 'Installing GeoLite2 database.', getConfigurationTable);
|
||||
});
|
||||
|
||||
$("#uninstall_geoip_db").click(function () {
|
||||
var msg = 'Are you sure you want to uninstall the GeoLite2 database?<br /><br />' +
|
||||
'You will not be able to lookup IP address geolocation info.';
|
||||
var url = 'uninstall_geoip_db';
|
||||
confirmAjaxCall(url, msg, 'Uninstalling GeoLite2 database.', getConfigurationTable);
|
||||
confirmAjaxCall(url, msg, null, 'Uninstalling GeoLite2 database.', getConfigurationTable);
|
||||
});
|
||||
|
||||
$('.guidelines-modal-link').on('click', function (e) {
|
||||
|
@ -168,5 +127,11 @@ DOCUMENTATION :: END
|
|||
$('#support-modal').modal('hide');
|
||||
});
|
||||
});
|
||||
|
||||
$('body').tooltip({
|
||||
selector: '[data-toggle="tooltip"]',
|
||||
container: 'body'
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
904
data/interfaces/default/css/jquery.scrollbar.css
Normal file
|
@ -0,0 +1,904 @@
|
|||
/*************** SCROLLBAR BASE CSS ***************/
|
||||
.scroll-wrapper {
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
position: relative;
|
||||
}
|
||||
.scroll-wrapper > .scroll-content {
|
||||
border: none !important;
|
||||
box-sizing: content-box !important;
|
||||
height: auto;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
max-height: none;
|
||||
max-width: none !important;
|
||||
overflow: scroll !important;
|
||||
padding: 0;
|
||||
position: relative !important;
|
||||
top: 0;
|
||||
width: auto !important;
|
||||
}
|
||||
.scroll-wrapper > .scroll-content::-webkit-scrollbar {
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
.scroll-wrapper.scroll--rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.scroll-element {
|
||||
box-sizing: content-box;
|
||||
display: none;
|
||||
}
|
||||
.scroll-element div {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.scroll-element .scroll-bar,
|
||||
.scroll-element .scroll-arrow {
|
||||
cursor: default;
|
||||
}
|
||||
.scroll-element.scroll-x.scroll-scrollx_visible, .scroll-element.scroll-y.scroll-scrolly_visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.scroll-textarea {
|
||||
border: 1px solid #cccccc;
|
||||
border-top-color: #999999;
|
||||
}
|
||||
.scroll-textarea > .scroll-content {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.scroll-textarea > .scroll-content > textarea {
|
||||
border: none !important;
|
||||
box-sizing: border-box;
|
||||
height: 100% !important;
|
||||
margin: 0;
|
||||
max-height: none !important;
|
||||
max-width: none !important;
|
||||
overflow: scroll !important;
|
||||
outline: none;
|
||||
padding: 2px;
|
||||
position: relative !important;
|
||||
top: 0;
|
||||
width: 100% !important;
|
||||
}
|
||||
.scroll-textarea > .scroll-content > textarea::-webkit-scrollbar {
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
/*************** SIMPLE INNER SCROLLBAR ***************/
|
||||
.scrollbar-inner > .scroll-element,
|
||||
.scrollbar-inner > .scroll-element div {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-x {
|
||||
bottom: 2px;
|
||||
height: 8px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
right: 2px;
|
||||
top: 0;
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_outer {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_outer,
|
||||
.scrollbar-inner > .scroll-element .scroll-element_track,
|
||||
.scrollbar-inner > .scroll-element .scroll-bar {
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_track,
|
||||
.scrollbar-inner > .scroll-element .scroll-bar {
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
|
||||
filter: alpha(opacity=40);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_track {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-bar {
|
||||
background-color: #c2c2c2;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element:hover .scroll-bar {
|
||||
background-color: #919191;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-draggable .scroll-bar {
|
||||
background-color: #919191;
|
||||
}
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track {
|
||||
left: -12px;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track {
|
||||
top: -12px;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size {
|
||||
left: -12px;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size {
|
||||
top: -12px;
|
||||
}
|
||||
|
||||
/*************** SIMPLE OUTER SCROLLBAR ***************/
|
||||
.scrollbar-outer > .scroll-element,
|
||||
.scrollbar-outer > .scroll-element div {
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 12px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x .scroll-element_outer {
|
||||
height: 8px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-y .scroll-element_outer {
|
||||
left: 2px;
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-element_outer {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-element_track {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-element_outer,
|
||||
.scrollbar-outer > .scroll-element .scroll-element_track,
|
||||
.scrollbar-outer > .scroll-element .scroll-bar {
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-bar {
|
||||
background-color: #d9d9d9;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-bar:hover {
|
||||
background-color: #c2c2c2;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-draggable .scroll-bar {
|
||||
background-color: #919191;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
.scrollbar-outer > .scroll-content.scroll-scrolly_visible {
|
||||
left: -12px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-content.scroll-scrollx_visible {
|
||||
top: -12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x .scroll-bar {
|
||||
min-width: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-y .scroll-bar {
|
||||
min-height: 10px;
|
||||
}
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track {
|
||||
left: -14px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track {
|
||||
top: -14px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size {
|
||||
left: -14px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size {
|
||||
top: -14px;
|
||||
}
|
||||
|
||||
/*************** SCROLLBAR MAC OS X ***************/
|
||||
.scrollbar-macosx > .scroll-element,
|
||||
.scrollbar-macosx > .scroll-element div {
|
||||
background: none;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element .scroll-element_track {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element .scroll-bar {
|
||||
background-color: #6C6E71;
|
||||
display: block;
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
-webkit-border-radius: 7px;
|
||||
-moz-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
-ms-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
|
||||
.scrollbar-macosx:hover > .scroll-element .scroll-bar,
|
||||
.scrollbar-macosx > .scroll-element.scroll-draggable .scroll-bar {
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
|
||||
filter: alpha(opacity=70);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-x {
|
||||
bottom: 0px;
|
||||
height: 0px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
overflow: visible;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 0px;
|
||||
top: 0;
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
.scrollbar-macosx > .scroll-element.scroll-x .scroll-bar {
|
||||
height: 7px;
|
||||
min-width: 10px;
|
||||
top: -9px;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-y .scroll-bar {
|
||||
left: -9px;
|
||||
min-height: 10px;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-x .scroll-element_outer {
|
||||
left: 2px;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-x .scroll-element_size {
|
||||
left: -4px;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-y .scroll-element_outer {
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-y .scroll-element_size {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-macosx > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size {
|
||||
left: -11px;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size {
|
||||
top: -11px;
|
||||
}
|
||||
|
||||
/*************** SCROLLBAR LIGHT ***************/
|
||||
.scrollbar-light > .scroll-element,
|
||||
.scrollbar-light > .scroll-element div {
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element .scroll-element_outer {
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element .scroll-element_size {
|
||||
background: #dbdbdb;
|
||||
background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiZGJkYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlOGU4ZTgiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+");
|
||||
background: -moz-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%);
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(0%, #dbdbdb), color-stop(100%, #e8e8e8));
|
||||
background: -webkit-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%);
|
||||
background: -o-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%);
|
||||
background: -ms-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%);
|
||||
background: linear-gradient(to right, #dbdbdb 0%, #e8e8e8 100%);
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 17px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 17px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element .scroll-bar {
|
||||
background: #fefefe;
|
||||
background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZmVmZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+");
|
||||
background: -moz-linear-gradient(left, #fefefe 0%, #f5f5f5 100%);
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(0%, #fefefe), color-stop(100%, #f5f5f5));
|
||||
background: -webkit-linear-gradient(left, #fefefe 0%, #f5f5f5 100%);
|
||||
background: -o-linear-gradient(left, #fefefe 0%, #f5f5f5 100%);
|
||||
background: -ms-linear-gradient(left, #fefefe 0%, #f5f5f5 100%);
|
||||
background: linear-gradient(to right, #fefefe 0%, #f5f5f5 100%);
|
||||
border: 1px solid #dbdbdb;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
.scrollbar-light > .scroll-content.scroll-scrolly_visible {
|
||||
left: -17px;
|
||||
margin-left: 17px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-content.scroll-scrollx_visible {
|
||||
top: -17px;
|
||||
margin-top: 17px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x .scroll-bar {
|
||||
height: 10px;
|
||||
min-width: 10px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y .scroll-bar {
|
||||
left: 0px;
|
||||
min-height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x .scroll-element_outer {
|
||||
height: 12px;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x .scroll-element_size {
|
||||
left: -4px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y .scroll-element_outer {
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y .scroll-element_size {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size {
|
||||
left: -19px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size {
|
||||
top: -19px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track {
|
||||
left: -19px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track {
|
||||
top: -19px;
|
||||
}
|
||||
|
||||
/*************** SCROLLBAR RAIL ***************/
|
||||
.scrollbar-rail > .scroll-element,
|
||||
.scrollbar-rail > .scroll-element div {
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-element_size {
|
||||
background-color: #999;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-element_size {
|
||||
background-color: #666;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 12px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
padding: 3px 0 2px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
padding: 0 2px 0 3px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-bar {
|
||||
background-color: #d0b9a0;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-bar {
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
.scrollbar-rail > .scroll-content.scroll-scrolly_visible {
|
||||
left: -17px;
|
||||
margin-left: 17px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-content.scroll-scrollx_visible {
|
||||
margin-top: 17px;
|
||||
top: -17px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x .scroll-bar {
|
||||
height: 10px;
|
||||
min-width: 10px;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y .scroll-bar {
|
||||
left: 1px;
|
||||
min-height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x .scroll-element_outer {
|
||||
height: 15px;
|
||||
left: 5px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x .scroll-element_size {
|
||||
height: 2px;
|
||||
left: -10px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y .scroll-element_outer {
|
||||
top: 5px;
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y .scroll-element_size {
|
||||
left: 5px;
|
||||
top: -10px;
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size {
|
||||
left: -25px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size {
|
||||
top: -25px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track {
|
||||
left: -25px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track {
|
||||
top: -25px;
|
||||
}
|
||||
|
||||
/*************** SCROLLBAR DYNAMIC ***************/
|
||||
.scrollbar-dynamic > .scroll-element,
|
||||
.scrollbar-dynamic > .scroll-element div {
|
||||
background: none;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x {
|
||||
bottom: 2px;
|
||||
height: 7px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 2px;
|
||||
top: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element .scroll-element_outer {
|
||||
opacity: 0.3;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element .scroll-element_size {
|
||||
background-color: #cccccc;
|
||||
opacity: 0;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
-webkit-transition: opacity 0.2s;
|
||||
-moz-transition: opacity 0.2s;
|
||||
-o-transition: opacity 0.2s;
|
||||
-ms-transition: opacity 0.2s;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element .scroll-bar {
|
||||
background-color: #6c6e71;
|
||||
-webkit-border-radius: 7px;
|
||||
-moz-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x .scroll-bar {
|
||||
bottom: 0;
|
||||
height: 7px;
|
||||
min-width: 24px;
|
||||
top: auto;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y .scroll-bar {
|
||||
left: auto;
|
||||
min-height: 24px;
|
||||
right: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_outer {
|
||||
bottom: 0;
|
||||
top: auto;
|
||||
left: 2px;
|
||||
-webkit-transition: height 0.2s;
|
||||
-moz-transition: height 0.2s;
|
||||
-o-transition: height 0.2s;
|
||||
-ms-transition: height 0.2s;
|
||||
transition: height 0.2s;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_outer {
|
||||
left: auto;
|
||||
right: 0;
|
||||
top: 2px;
|
||||
-webkit-transition: width 0.2s;
|
||||
-moz-transition: width 0.2s;
|
||||
-o-transition: width 0.2s;
|
||||
-ms-transition: width 0.2s;
|
||||
transition: width 0.2s;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_size {
|
||||
left: -4px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_size {
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size {
|
||||
left: -11px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size {
|
||||
top: -11px;
|
||||
}
|
||||
|
||||
/* hover & drag */
|
||||
.scrollbar-dynamic > .scroll-element:hover .scroll-element_outer,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer {
|
||||
overflow: hidden;
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
|
||||
filter: alpha(opacity=70);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-element_size,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-element_size {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-bar,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-bar {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x:hover .scroll-element_outer,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x.scroll-draggable .scroll-element_outer {
|
||||
height: 20px;
|
||||
min-height: 7px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y:hover .scroll-element_outer,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y.scroll-draggable .scroll-element_outer {
|
||||
min-width: 7px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
/*************** SCROLLBAR GOOGLE CHROME ***************/
|
||||
.scrollbar-chrome > .scroll-element,
|
||||
.scrollbar-chrome > .scroll-element div {
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element .scroll-element_track {
|
||||
background: #f1f1f1;
|
||||
border: 1px solid #dbdbdb;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 16px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element .scroll-bar {
|
||||
background-color: #d9d9d9;
|
||||
border: 1px solid #bdbdbd;
|
||||
cursor: default;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element .scroll-bar:hover {
|
||||
background-color: #c2c2c2;
|
||||
border-color: #a9a9a9;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-draggable .scroll-bar {
|
||||
background-color: #919191;
|
||||
border-color: #7e7e7e;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
.scrollbar-chrome > .scroll-content.scroll-scrolly_visible {
|
||||
left: -16px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-content.scroll-scrollx_visible {
|
||||
top: -16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-bar {
|
||||
height: 8px;
|
||||
min-width: 10px;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-bar {
|
||||
left: 3px;
|
||||
min-height: 10px;
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-element_outer {
|
||||
border-left: 1px solid #dbdbdb;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-element_track {
|
||||
height: 14px;
|
||||
left: -3px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-element_size {
|
||||
height: 14px;
|
||||
left: -4px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-element_outer {
|
||||
border-top: 1px solid #dbdbdb;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-element_track {
|
||||
top: -3px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-element_size {
|
||||
top: -4px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size {
|
||||
left: -19px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size {
|
||||
top: -19px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track {
|
||||
left: -19px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track {
|
||||
top: -19px;
|
||||
}
|
|
@ -34,7 +34,7 @@ table.display {
|
|||
margin: 0 auto;
|
||||
clear: both;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-size: 12px;
|
||||
line-height: 25px;
|
||||
/* Note Firefox 3.5 and before have a bug with border-collapse
|
||||
* ( https://bugzilla.mozilla.org/show%5Fbug.cgi?id=155955 )
|
||||
|
@ -332,4 +332,86 @@ div.box {
|
|||
}
|
||||
td.no-wrap, th.no-wrap {
|
||||
white-space:nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Custom styles
|
||||
*/
|
||||
|
||||
table.display,
|
||||
table.display tr.shown + tr table[id^='history_child'],
|
||||
table.display tr.shown + tr table[id^='media_info_child'],
|
||||
table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] {
|
||||
table-layout: auto;
|
||||
}
|
||||
table.display tr.shown + tr div.slider {
|
||||
display: none;
|
||||
}
|
||||
table.display tr.shown + tr > td {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
table.display tr.shown + tr:hover {
|
||||
background-color: rgba(255,255,255,0);
|
||||
}
|
||||
table.display tr.shown + tr:hover a,
|
||||
table.display tr.shown + tr td:hover a,
|
||||
table.display tr.shown + tr .pagination > .active > a,
|
||||
table.display tr.shown + tr .pagination > .active > a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
table.display tr.shown + tr table[id^='history_child'] td:hover a,
|
||||
table.display tr.shown + tr table[id^='media_info_child'] > tr > td:hover a,
|
||||
table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] td:hover a {
|
||||
color: #cc7b19;
|
||||
}
|
||||
table.display tr.shown + tr .pagination > .disabled > a,
|
||||
table.display tr.shown + tr .pagination > .disabled > a:hover {
|
||||
color: #444444;
|
||||
}
|
||||
table.display tr.shown + tr .pagination > li > a:hover {
|
||||
color: #e9a049;
|
||||
}
|
||||
table.display tr.odd td,
|
||||
table.display tr.even td {
|
||||
padding: 5px 10px !important;
|
||||
}
|
||||
table[id^='history_child'] {
|
||||
margin-top: 0;
|
||||
opacity: .6;
|
||||
}
|
||||
table[id^='media_info_child'] {
|
||||
margin-top: 0;
|
||||
}
|
||||
div[id^='history_child'] thead th,
|
||||
div[id^='media_info_child'] thead th {
|
||||
line-height: 0;
|
||||
height: 0 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
div[id^='history_child'] div.row,
|
||||
div[id^='media_info_child'] div.row {
|
||||
margin: 0;
|
||||
}
|
||||
div[id^='history_child'] div.col-sm-12,
|
||||
div[id^='media_info_child'] div.col-sm-12 {
|
||||
padding: 0;
|
||||
}
|
||||
div[id^='history_child'] div.dataTables_scrollBody,
|
||||
div[id^='media_info_child'] div.dataTables_scrollBody {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
div[id^='media_info_child'] div[id^='media_info_child'] div.dataTables_scrollHead thead th {
|
||||
line-height: 25px;
|
||||
height: 35px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
.current-activity-row {
|
||||
background-color: rgba(255,255,255,.1) !important;
|
||||
}
|
||||
.current-activity-row:hover {
|
||||
background-color: rgba(255,255,255,0.125) !important;
|
||||
}
|
||||
|
|
1
data/interfaces/default/css/selectize.min.css
vendored
Normal file
|
@ -1,328 +0,0 @@
|
|||
<%doc>
|
||||
USAGE DOCUMENTATION :: PLEASE LEAVE THIS AT THE TOP OF THIS FILE
|
||||
|
||||
For Mako templating syntax documentation please visit: http://docs.makotemplates.org/en/latest/
|
||||
|
||||
Filename: current_activity.html
|
||||
Version: 0.1
|
||||
Variable names: data [list]
|
||||
|
||||
data :: Usable parameters
|
||||
|
||||
data['stream_count'] Returns the current number of active streams
|
||||
data['sessions'] Returns an array containing session data
|
||||
|
||||
data[sessions] :: Usable parameters
|
||||
|
||||
== Global keys ==
|
||||
session_key Returns a unique session id for the active stream
|
||||
rating_key Returns the unique identifier for the media item.
|
||||
media_index Returns the index of the media item.
|
||||
parent_media_index Returns the index of the media item's parent.
|
||||
media_type Returns the type of session. Either 'track', 'episode' or 'movie'.
|
||||
thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.
|
||||
bif_thumb Returns the location of the item's bif thumbnail. Use with pms_image_proxy.
|
||||
art Returns the location of the item's artwork
|
||||
progress_percent Returns the current progress of the item. 0 to 100.
|
||||
user Returns the name of the user owning the session.
|
||||
user_id Returns the Plex user id if available.
|
||||
machine_id Returns the machine id of the players being used.
|
||||
friendly_name Returns the friendlly name of the user owning the session.
|
||||
user_thumb Returns the profile picture of the user owning the session.
|
||||
state Returns the state of the current session. Either 'playing', 'paused' or 'buffering'.
|
||||
title Returns the name of the episode, movie or music track.
|
||||
year Returns the year of the episode, movie, or clip.
|
||||
ip_address Returns the ip address of the stream.
|
||||
player Returns the name of the platform used to play the stream.
|
||||
platform Returns the type of platform used to play the stream.
|
||||
throttled Returns true if the transcode session is throttled.
|
||||
transcode_progress Returns the current transcode progress of the item. 0 to 100.
|
||||
transcode_speed Returns the current transcode speed of the item.
|
||||
audio_decision Returns the audio transcode decision. Either 'transcode', 'copy' or 'direct play'.
|
||||
audio_codec Returns the name of the audio codec.
|
||||
audio_channels Returns the number of audio channels.
|
||||
grandparent_title Returns the title of the item's grandparent.
|
||||
parent_title Returns the title of the item's parent.
|
||||
video_decision Returns the video transcode decision. Either 'transcode', 'copy' or 'direct play'.
|
||||
video_codec Returns the name of the video codec.
|
||||
height Returns the value of the video height.
|
||||
width Returns the value of the video width.
|
||||
container Returns the value of the media container.
|
||||
bitrate Returns the value of the media bitrate.
|
||||
video_resolution Returns the value of the video resolution.
|
||||
video_framerate Returns the value of the video framerate.
|
||||
video_aspect_ratio Returns the value of the video aspect ratio.
|
||||
transcode_audio_channels Returns the amount of audio channels if there is a transcode session.
|
||||
transcode_audio_codec Returns the name of the audio codec if there is a transcode session.
|
||||
transcode_video_codec Returns the name of the video codec if there is a transcode session.
|
||||
transcode_width Returns the video width if there is a transcode session.
|
||||
transcode_height Returns the video height if there is a transcode session.
|
||||
transcode_container Returns the value of media container if there is a transcode session.
|
||||
transcode_protocol Returns the value of media protocol if there is a transcode session.
|
||||
indexes Returns true if the media has media indexes and are enabled
|
||||
|
||||
DOCUMENTATION :: END
|
||||
</%doc>
|
||||
|
||||
% if data is not None:
|
||||
% if data['stream_count'] != '0':
|
||||
% for a in data['sessions']:
|
||||
<div class="dashboard-instance" id="instance-${a['session_key']}">
|
||||
% if (a['media_type'] == 'movie' or a['media_type'] == 'episode' or a['media_type'] == 'track') and a['rating_key']:
|
||||
<a href="info?rating_key=${a['rating_key']}">
|
||||
% else:
|
||||
<a href="#">
|
||||
% endif
|
||||
<div class="dashboard-activity-poster">
|
||||
% if not a['art'].startswith('interfaces') or not a['thumb'].startswith('interfaces'):
|
||||
% if (a['media_type'] == 'movie' and not a['indexes']) or (a['indexes'] and not a['view_offset']):
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['art']}&width=500&height=280&fallback=art);"></div>
|
||||
% elif (a['media_type'] == 'episode' and not a['indexes']) or (a['indexes'] and not a['view_offset']):
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['art']}&width=500&height=280&fallback=art);"></div>
|
||||
% elif a['indexes']:
|
||||
<div class="dashboard-activity-poster-face bif" style="background-image: url(pms_image_proxy?img=${a['bif_thumb']}&width=500&height=280&fallback=art); display: none;"></div>
|
||||
% else:
|
||||
% if a['media_type'] == 'track':
|
||||
<div class="dashboard-activity-cover-face-bg" style="background-image: url(pms_image_proxy?img=${a['thumb']}&width=300&height=300&fallback=cover);"></div>
|
||||
<div class="dashboard-activity-cover-face" style="background-image: url(pms_image_proxy?img=${a['thumb']}&width=300&height=300&fallback=cover);"></div>
|
||||
% elif a['media_type'] == 'clip':
|
||||
% if a['art'][:4] == 'http':
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(${a['art']});"></div>
|
||||
% elif a['thumb'][:4] == 'http':
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(${a['thumb']});"></div>
|
||||
% else:
|
||||
% if a['art']:
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['art']}&width=500&height=280&fallback=art);"></div>
|
||||
% else:
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['thumb']}&width=500&height=280&fallback=art);"></div>
|
||||
% endif
|
||||
% endif
|
||||
% elif a['media_type'] == 'photo':
|
||||
<div class="dashboard-activity-poster-face bif" style="background-image: url(pms_image_proxy?img=${a['thumb']}&width=500&height=500&fallback=cover);"></div>
|
||||
% else:
|
||||
<div class="dashboard-activity-cover-face" style="background-image: url(pms_image_proxy?img=${a['thumb']}&width=300&height=300&fallback=cover);"></div>
|
||||
% endif
|
||||
% endif
|
||||
% else:
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(${a['art']});"></div>
|
||||
% endif
|
||||
% if _session['user_group'] == 'admin':
|
||||
<span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
|
||||
% endif
|
||||
<div class="dashboard-activity-button-info">
|
||||
<button type="button" class="btn btn-activity-info btn-lg" data-target="#stream-${a['session_key']}">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div id="stream-${a['session_key']}" class="dashboard-activity-info-details-overlay">
|
||||
<div class="dashboard-activity-info-details-content">
|
||||
<div id="platform-${a['session_key']}" title="${a['platform']}">
|
||||
<script>
|
||||
$("#platform-${a['session_key']}").html("<div class='dashboard-activity-info-platform-box' style='background-image: url(" + getPlatformImagePath('${a['platform']}') + ");'>");
|
||||
</script>
|
||||
</div>
|
||||
<div class="dashboard-activity-info-platform">
|
||||
<strong>${a['player']}</strong><br />
|
||||
% if a['state'] == 'playing':
|
||||
State <strong>Playing</strong>
|
||||
% elif a['state'] == 'paused':
|
||||
State <strong>Paused</strong>
|
||||
% elif a['state'] == 'buffering':
|
||||
State <strong>Buffering</strong>
|
||||
% endif
|
||||
</div>
|
||||
% if a['media_type'] == 'track':
|
||||
% if a['audio_decision'] == 'direct play':
|
||||
Stream <strong>Direct Play</strong>
|
||||
% elif a['audio_decision'] == 'copy':
|
||||
Stream <strong>Direct Stream</strong>
|
||||
% else:
|
||||
Stream <strong>Transcoding
|
||||
(Speed: ${a['transcode_speed']})
|
||||
% if a['throttled'] == '1':
|
||||
(Throttled)
|
||||
% endif
|
||||
</strong>
|
||||
% endif
|
||||
<br />
|
||||
% if a['audio_decision'] == 'direct play':
|
||||
Audio <strong>Direct Play (${a['audio_codec']}) (${a['audio_channels']}ch)</strong>
|
||||
% elif a['audio_decision'] == 'copy':
|
||||
Audio <strong>Direct Stream (${a['transcode_audio_codec']}) (${a['transcode_audio_channels']}ch)</strong>
|
||||
% elif a['audio_decision'] == 'transcode':
|
||||
Audio <strong>Transcode (${a['transcode_audio_codec']}) (${a['transcode_audio_channels']}ch)</strong>
|
||||
% endif
|
||||
% elif a['media_type'] == 'episode' or a['media_type'] == 'movie' or a['media_type'] == 'clip':
|
||||
% if a['video_decision'] == 'direct play' and a['audio_decision'] == 'direct play':
|
||||
Stream <strong>Direct Play</strong>
|
||||
% elif a['video_decision'] == 'copy' and a['audio_decision'] == 'copy':
|
||||
Stream <strong>Direct Stream</strong>
|
||||
% else:
|
||||
Stream <strong>Transcoding
|
||||
(Speed: ${a['transcode_speed']})
|
||||
% if a['throttled'] == '1':
|
||||
(Throttled)
|
||||
% endif
|
||||
</strong>
|
||||
% endif
|
||||
<br />
|
||||
% if a['video_decision'] == 'direct play':
|
||||
Video <strong>Direct Play (${a['video_codec']}) (${a['width']}x${a['height']})</strong>
|
||||
% elif a['video_decision'] == 'copy':
|
||||
Video <strong>Direct Stream (${a['transcode_video_codec']}) (${a['width']}x${a['height']})</strong>
|
||||
% elif a['video_decision'] == 'transcode':
|
||||
Video <strong>Transcode (${a['transcode_video_codec']}) (${a['transcode_width']}x${a['transcode_height']})</strong>
|
||||
% endif
|
||||
<br />
|
||||
% if a['audio_decision'] == 'direct play':
|
||||
Audio <strong>Direct Play (${a['audio_codec']}) (${a['audio_channels']}ch)</strong>
|
||||
% elif a['audio_decision'] == 'copy':
|
||||
Audio <strong>Direct Stream (${a['transcode_audio_codec']}) (${a['transcode_audio_channels']}ch)</strong>
|
||||
% elif a['audio_decision'] == 'transcode':
|
||||
Audio <strong>Transcode (${a['transcode_audio_codec']}) (${a['transcode_audio_channels']}ch)</strong>
|
||||
% endif
|
||||
% elif a['media_type'] == 'photo':
|
||||
% if a['video_decision'] == 'direct play':
|
||||
Stream <strong>Direct Play</strong>
|
||||
% elif a['video_decision'] == 'copy':
|
||||
Stream <strong>Direct Stream</strong>
|
||||
% else:
|
||||
Stream <strong>
|
||||
Transcoding
|
||||
(Speed: ${a['transcode_speed']})
|
||||
% if a['throttled'] == '1':
|
||||
(Throttled)
|
||||
% endif
|
||||
</strong>
|
||||
% endif
|
||||
% endif
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
% if a['media_type'] != 'photo':
|
||||
<div class="dashboard-activity-poster-info-bar">
|
||||
<div class="dashboard-activity-poster-info-ip-address">
|
||||
% if a['ip_address']:
|
||||
<span>IP: ${a['ip_address']}</span>
|
||||
% else:
|
||||
<span>IP: N/A</span>
|
||||
% endif
|
||||
<br />
|
||||
ETA:
|
||||
<span id="stream-eta-${a['session_key']}">
|
||||
<script>
|
||||
$("#stream-eta-${a['session_key']}").html(moment().add(parseInt(${a['duration']}) - parseInt(${a['view_offset']}), 'milliseconds').format(time_format));
|
||||
</script>
|
||||
</span>
|
||||
</div>
|
||||
<div class="dashboard-activity-poster-info-time">
|
||||
<span class="progress_time">${a['view_offset']}</span>/<span class="progress_time">${a['duration']}</span>
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
% if (a['media_type'] == 'movie' or a['media_type'] == 'episode' or a['media_type'] == 'track') and a['rating_key']:
|
||||
</a>
|
||||
% else:
|
||||
</a>
|
||||
% endif
|
||||
<div class="dashboard-activity-progress">
|
||||
<div class="dashboard-activity-progress-bar">
|
||||
<div class="bufferbar" style="width: ${a['transcode_progress']}%" data-toggle="tooltip" title="Transcoder Progress">${a['transcode_progress']}%</div>
|
||||
<div class="bar" style="width: ${a['progress_percent']}%" data-toggle="tooltip" title="Stream Progress">${a['progress_percent']}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-wrapper">
|
||||
% if a['user_id']:
|
||||
<a href="user?user_id=${a['user_id']}">
|
||||
<div class="dashboard-activity-metadata-user-thumb" style="background-image: url(${a['user_thumb']});"></div>
|
||||
</a>
|
||||
% else:
|
||||
<div class="dashboard-activity-metadata-user-thumb" style="background-image: url(${a['user_thumb']});"></div>
|
||||
% endif
|
||||
<div class="dashboard-activity-metadata-title">
|
||||
% if a['state'] == 'playing':
|
||||
<i class="fa fa-play"></i>
|
||||
% elif a['state'] == 'paused':
|
||||
<i class="fa fa-pause"></i>
|
||||
% elif a['state'] == 'buffering':
|
||||
<i class="fa fa-spinner"></i>
|
||||
% endif
|
||||
% if a['rating_key']:
|
||||
% if a['media_type'] == 'episode':
|
||||
<a href="info?rating_key=${a['rating_key']}" title="${a['grandparent_title']} - ${a['title']}">${a['grandparent_title']} - ${a['title']}</a>
|
||||
% elif a['media_type'] == 'movie':
|
||||
<a href="info?rating_key=${a['rating_key']}" title="${a['title']}">${a['title']}</a>
|
||||
% elif a['media_type'] == 'clip':
|
||||
<span title="${a['title']}">${a['title']}</span>
|
||||
% elif a['media_type'] == 'track':
|
||||
<a href="info?rating_key=${a['rating_key']}" title="${a['grandparent_title']} - ${a['title']}">${a['grandparent_title']} - ${a['title']}</a>
|
||||
% elif a['media_type'] == 'photo':
|
||||
<span title="${a['parent_title']}">${a['parent_title']}</span>
|
||||
% else:
|
||||
<span title="${a['title']}">${a['title']}</span>
|
||||
% endif
|
||||
% else:
|
||||
${a['title']}
|
||||
% endif
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-subtitle">
|
||||
% if a['rating_key']:
|
||||
% if a['media_type'] == 'episode':
|
||||
<span title="S${a['parent_media_index']} · E${a['media_index']}">S${a['parent_media_index']} · E${a['media_index']}</span>
|
||||
% elif a['media_type'] == 'movie':
|
||||
<span title="${a['year']}">${a['year']}</span>
|
||||
% elif a['media_type'] == 'track':
|
||||
<a href="info?rating_key=${a['parent_rating_key']}" title="${a['parent_title']}">${a['parent_title']}</a>
|
||||
% elif a['media_type'] == 'photo':
|
||||
<span title="${a['title']}">${a['title']}</span>
|
||||
% else:
|
||||
<span title="${a['year']}">${a['year']}</span>
|
||||
% endif
|
||||
% endif
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-user">
|
||||
% if a['user_id']:
|
||||
<a href="user?user_id=${a['user_id']}" title="${a['friendly_name']}">${a['friendly_name']}</a>
|
||||
% else:
|
||||
${a['friendly_name']}
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
% endfor
|
||||
<script>
|
||||
// When using bif indexes make the image transition a little smoother.
|
||||
$('.bif').each(function() {
|
||||
$(this).hide().fadeIn(1000);
|
||||
});
|
||||
|
||||
// Convert timestamps to readable times
|
||||
$('.progress_time').each(function(index) {
|
||||
$(this).html(millisecondsToMinutes($(this).text(), false));
|
||||
});
|
||||
|
||||
// Show/Hide activity info
|
||||
$('.btn-activity-info').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
$($(this).attr('data-target')).toggle();
|
||||
});
|
||||
|
||||
// Add hover class to dashboard-instance
|
||||
$('.dashboard-activity-poster, .dashboard-activity-progress-bar').hover(function() {
|
||||
$(this).closest('.dashboard-instance').addClass('hover');
|
||||
}, function() {
|
||||
$(this).closest('.dashboard-instance').removeClass('hover');
|
||||
});
|
||||
|
||||
$('.bar, .bufferbar').tooltip({container: 'body', placement: 'right', delay: 50});
|
||||
</script>
|
||||
% else:
|
||||
<div class="text-muted">Nothing is currently being watched.</div><br>
|
||||
% endif
|
||||
% else:
|
||||
<div class="text-muted">There was an error communicating with your Plex Server. Please check your <a
|
||||
href="settings">settings</a>.
|
||||
</div><br>
|
||||
% endif
|
|
@ -30,7 +30,7 @@ year Returns the year of the episode, movie, or clip.
|
|||
ip_address Returns the ip address of the stream.
|
||||
player Returns the name of the platform used to play the stream.
|
||||
platform Returns the type of platform used to play the stream.
|
||||
throttled Returns true if the transcode session is throttled.
|
||||
transcode_throttled Returns true if the transcode session is throttled.
|
||||
transcode_progress Returns the current transcode progress of the item. 0 to 100.
|
||||
transcode_speed Returns the current transcode speed of the item.
|
||||
audio_decision Returns the audio transcode decision. Either 'transcode', 'copy' or 'direct play'.
|
||||
|
@ -59,169 +59,296 @@ indexes Returns true if the media has media indexes and are
|
|||
DOCUMENTATION :: END
|
||||
</%doc>
|
||||
|
||||
% if data is not None:
|
||||
% if session is not None:
|
||||
<%
|
||||
from collections import defaultdict
|
||||
from urllib import quote
|
||||
|
||||
from plexpy import helpers
|
||||
data['indexes'] = helpers.cast_to_int(data['indexes'])
|
||||
import plexpy
|
||||
%>
|
||||
<div class="dashboard-instance" id="instance-${data['session_key']}" data-id="${data['session_key']}">
|
||||
<div class="dashboard-hover-container">
|
||||
% if (data['media_type'] == 'movie' or data['media_type'] == 'episode' or data['media_type'] == 'track') and data['rating_key']:
|
||||
<a href="info?rating_key=${data['rating_key']}">
|
||||
<% data = defaultdict(lambda: 'Unknown', **session) %>
|
||||
<% sk = data['session_key'] %>
|
||||
<div class="dashboard-activity-instance" id="activity-instance-${sk}" data-key="${sk}" data-id="${data['session_id']}"
|
||||
data-rating_key="${data['rating_key']}" data-parent_rating_key="${data['parent_rating_key']}" data-grandparent_rating_key="${data['grandparent_rating_key']}">
|
||||
<div class="dashboard-activity-container">
|
||||
<div class="dashboard-activity-background-overlay">
|
||||
% if data['channel_stream'] == '0':
|
||||
<div id="background-${sk}" class="dashboard-activity-background" style="background-image: url(pms_image_proxy?img=${data['art']}&width=500&height=280&fallback=art&refresh=true);"></div>
|
||||
% else:
|
||||
<a href="#">
|
||||
% if (data['art'] and data['art'].startswith('http')) or (data['thumb'] and data['thumb'].startswith('http')):
|
||||
<div id="background-${sk}" class="dashboard-activity-background" style="background-image: url(${data['art']});"></div>
|
||||
% else:
|
||||
<!--Hacky solution to escape the image url until I come up with something better-->
|
||||
<div id="background-${sk}" class="dashboard-activity-background" style="background-image: url(pms_image_proxy?img=${quote(data['art'] or data['thumb'])}&width=500&height=280&fallback=art&refresh=true&clip=true);"></div>
|
||||
% endif
|
||||
<div class="dashboard-activity-poster" id="poster-${data['session_key']}">
|
||||
% if not data['art'].startswith('interfaces') or not data['thumb'].startswith('interfaces'):
|
||||
% if (data['media_type'] == 'movie' and not data['indexes']) or (data['indexes'] and not data['view_offset']):
|
||||
<div id="bif-${data['session_key']}" class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${data['art']}&width=500&height=280&fallback=art);"></div>
|
||||
% elif (data['media_type'] == 'episode' and not data['indexes']) or (data['indexes'] and not data['view_offset']):
|
||||
<div id="bif-${data['session_key']}" class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${data['art']}&width=500&height=280&fallback=art);"></div>
|
||||
% elif data['indexes']:
|
||||
<div id="bif-${data['session_key']}" class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${data['bif_thumb']}&width=500&height=280&fallback=art); display: none;"></div>
|
||||
% endif
|
||||
<div class="dashboard-activity-poster-container hidden-xs">
|
||||
% if data['media_type'] == 'track':
|
||||
<div id="poster-${sk}-bg" class="dashboard-activity-poster-blur" style="background-image: url(pms_image_proxy?img=${data['parent_thumb']}&width=300&height=300&fallback=cover&refresh=true);"></div>
|
||||
% endif
|
||||
% if data['channel_stream'] == '0':
|
||||
% if data['media_type'] == 'movie':
|
||||
<a id="poster-url-${sk}" href="info?rating_key=${data['rating_key']}" title="${data['title']}">
|
||||
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(pms_image_proxy?img=${data['thumb']}&width=300&height=450&fallback=poster&refresh=true);"></div>
|
||||
</a>
|
||||
% elif data['media_type'] == 'episode':
|
||||
<a id="poster-url-${sk}" href="info?rating_key=${data['grandparent_rating_key']}" title="${data['grandparent_title']}">
|
||||
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(pms_image_proxy?img=${data['grandparent_thumb']}&width=300&height=450&fallback=poster&refresh=true);"></div>
|
||||
</a>
|
||||
% elif data['media_type'] == 'track':
|
||||
<a id="poster-url-${sk}" href="info?rating_key=${data['parent_rating_key']}" title="${data['parent_title']}">
|
||||
<div id="poster-${sk}" class="dashboard-activity-cover" style="background-image: url(pms_image_proxy?img=${data['parent_thumb']}&width=300&height=300&fallback=cover&refresh=true);"></div>
|
||||
</a>
|
||||
% elif data['media_type'] in ('photo', 'clip'):
|
||||
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(pms_image_proxy?img=${data['parent_thumb']}&width=300&height=450&fallback=poster&refresh=true);"></div>
|
||||
% else:
|
||||
% if data['media_type'] == 'track':
|
||||
<div class="dashboard-activity-cover-face-bg" style="background-image: url(pms_image_proxy?img=${data['thumb']}&width=300&height=300&fallback=cover);"></div>
|
||||
<div class="dashboard-activity-cover-face" style="background-image: url(pms_image_proxy?img=${data['thumb']}&width=300&height=300&fallback=cover);"></div>
|
||||
% elif data['media_type'] == 'clip':
|
||||
% if data['art'].startswith('http'):
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(${data['art']});"></div>
|
||||
% elif data['thumb'].startswith('http'):
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(${data['thumb']});"></div>
|
||||
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(images/art.png);"></div>
|
||||
% endif
|
||||
% else:
|
||||
% if data['channel_icon'].startswith('http'):
|
||||
<div id="poster-${sk}" class="dashboard-activity-poster-blur" style="background-image: url(${data['channel_icon']});"></div>
|
||||
<div id="poster-${sk}" class="dashboard-activity-cover" style="background-image: url(${data['channel_icon']});"></div>
|
||||
% else:
|
||||
% if data['art']:
|
||||
<!--Hacky solution to escape the image url until I come up with something better-->
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${quote(data['art'])}&width=500&height=280&fallback=art);"></div>
|
||||
% else:
|
||||
<!--Hacky solution to escape the image url until I come up with something better-->
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${quote(data['thumb'])}&width=500&height=280&fallback=art);"></div>
|
||||
<div id="poster-${sk}" class="dashboard-activity-poster-blur" style="background-image: url(pms_image_proxy?img=${data['channel_icon']}&width=300&height=300&fallback=cover&refresh=true);"></div>
|
||||
<div id="poster-${sk}" class="dashboard-activity-cover" style="background-image: url(pms_image_proxy?img=${data['channel_icon']}&width=300&height=300&fallback=cover&refresh=true);"></div>
|
||||
% endif
|
||||
% endif
|
||||
% elif data['media_type'] == 'photo':
|
||||
<div id="bif-${data['session_key']}" class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${data['thumb']}&width=500&height=500&fallback=cover);"></div>
|
||||
% else:
|
||||
<div class="dashboard-activity-cover-face" style="background-image: url(pms_image_proxy?img=${data['thumb']}&width=300&height=300&fallback=cover);"></div>
|
||||
% endif
|
||||
% endif
|
||||
% else:
|
||||
<div class="dashboard-activity-poster-face" style="background-image: url(${data['art']});"></div>
|
||||
% endif
|
||||
% if _session['user_group'] == 'admin':
|
||||
<span class="overlay-refresh-image left" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
|
||||
% endif
|
||||
<div class="dashboard-activity-button-info">
|
||||
<button type="button" class="btn btn-activity-info btn-lg" data-target="#stream-${data['session_key']}" data-id="${data['session_key']}">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div id="stream-${data['session_key']}" class="dashboard-activity-info-details-overlay">
|
||||
<div class="dashboard-activity-info-details-content">
|
||||
<div id="platform-${data['session_key']}" title="${data['platform']}">
|
||||
<script>
|
||||
$("#platform-${data['session_key']}").html("<div class='dashboard-activity-info-platform-box' style='background-image: url(" + getPlatformImagePath('${data['platform']}') + ");'>");
|
||||
</script>
|
||||
</div>
|
||||
<div class="dashboard-activity-info-platform">
|
||||
<strong>${data['player']}</strong><br />
|
||||
<span id="overlay-play-state-${data['session_key']}">
|
||||
% if data['state'] == 'playing':
|
||||
State <strong>Playing</strong>
|
||||
% elif data['state'] == 'paused':
|
||||
State <strong>Paused</strong>
|
||||
% elif data['state'] == 'buffering':
|
||||
State <strong>Buffering</strong>
|
||||
% endif
|
||||
</span>
|
||||
</div>
|
||||
<span id="transcode-state-${data['session_key']}">
|
||||
% if data['video_decision'] == 'transcode' or data['audio_decision'] == 'transcode':
|
||||
Stream <strong>Transcode (Speed: ${data['transcode_speed']})
|
||||
% if data['throttled'] == '1':
|
||||
(Throttled)
|
||||
% endif
|
||||
</strong>
|
||||
% elif data['video_decision'] == 'copy' or data['audio_decision'] == 'copy':
|
||||
Stream <strong>Direct Stream</strong>
|
||||
% else:
|
||||
Stream <strong>Direct Play</strong>
|
||||
% endif
|
||||
<br />
|
||||
% if data['video_decision'] and data['media_type'] != 'photo':
|
||||
% if data['video_decision'] == 'transcode':
|
||||
Video <strong>Transcode (${data['transcode_video_codec']}) (${data['transcode_width']}x${data['transcode_height']})</strong>
|
||||
% elif data['video_decision'] == 'copy':
|
||||
Video <strong>Direct Stream (${data['transcode_video_codec']}) (${data['width']}x${data['height']})</strong>
|
||||
% endif
|
||||
</div>
|
||||
<div class="dashboard-activity-info-icon">
|
||||
<%
|
||||
if not _session['user_group'] == 'admin' or not data['session_id']:
|
||||
no_terminate = '-no-terminate'
|
||||
else:
|
||||
no_terminate = ''
|
||||
%>
|
||||
<div id="platform-${sk}" class="dashboard-activity-info-platform${no_terminate} svg-icon platform-${data['platform_name']}" title="${data['platform']}"></div>
|
||||
% if _session['user_group'] == 'admin' and plexpy.CONFIG.PMS_PLEXPASS and data['session_id']:
|
||||
<div class="dashboard-activity-terminate-session" id="terminate-button-${sk}" data-key="${sk}" data-id="${data['session_id']}" data-toggle="tooltip" title="Terminate Stream">
|
||||
<i class="fa fa-times" style="padding-top: 8px;"></i>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
<div class="dashboard-activity-info-container">
|
||||
<div class="dashboard-activity-info-scroller scrollbar-macosx">
|
||||
<div class="dashboard-activity-info scoller-content">
|
||||
<ul class="list-unstyled dashboard-activity-info-list">
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Product</div>
|
||||
<div class="sub-value">${data['product']}</div>
|
||||
</li>
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Player</div>
|
||||
<div class="sub-value">${data['player']}</div>
|
||||
</li>
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Quality</div>
|
||||
<div class="sub-value" id="stream_quality-${sk}">
|
||||
% if data['media_type'] != 'photo' and data['quality_profile'] != 'Unknown':
|
||||
<%
|
||||
br = helpers.cast_to_int(data['stream_bitrate']) or ''
|
||||
if br:
|
||||
if br > 1000:
|
||||
br = '(' + str(round(br / 1000.0, 1)) + ' Mbps)'
|
||||
else:
|
||||
br = '(' + str(br) + ' kbps)'
|
||||
%>
|
||||
${data['quality_profile']} ${br}
|
||||
% else:
|
||||
Video <strong>Direct Play (${data['video_codec']}) (${data['width']}x${data['height']})</strong>
|
||||
${data['quality_profile']}
|
||||
% endif
|
||||
<br />
|
||||
% endif
|
||||
% if data['audio_decision']:
|
||||
% if data['audio_decision'] == 'transcode':
|
||||
Audio <strong>Transcode (${data['transcode_audio_codec']}) (${data['transcode_audio_channels']}ch)</strong>
|
||||
% elif data['audio_decision'] == 'copy':
|
||||
Audio <strong>Direct Stream (${data['transcode_audio_codec']}) (${data['transcode_audio_channels']}ch)</strong>
|
||||
% else:
|
||||
Audio <strong>Direct Play (${data['audio_codec']}) (${data['audio_channels']}ch)</strong>
|
||||
% endif
|
||||
% endif
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
% if data['media_type'] != 'photo':
|
||||
<div class="dashboard-activity-poster-info-bar">
|
||||
<div class="dashboard-activity-poster-info-ip-address">
|
||||
% if data['ip_address']:
|
||||
<span>IP: ${data['ip_address']}</span>
|
||||
% else:
|
||||
<span>IP: N/A</span>
|
||||
</div>
|
||||
</li>
|
||||
% if data['optimized_version'] == '1':
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Optimized</div>
|
||||
<div class="sub-value" id="optimized_version-${sk}">
|
||||
${data['optimized_version_profile']}
|
||||
</div>
|
||||
</li>
|
||||
% endif
|
||||
<br />
|
||||
ETA:
|
||||
<span id="stream-eta-${data['session_key']}">
|
||||
<script>
|
||||
$("#stream-eta-${data['session_key']}").html(moment().add(parseInt("${data['duration']}") - parseInt("${data['view_offset']}"), 'milliseconds').format(time_format));
|
||||
</script>
|
||||
</span>
|
||||
</div>
|
||||
<div class="dashboard-activity-poster-info-time">
|
||||
<span class="progress_time" id="stream-view-offset-${data['session_key']}">
|
||||
<script>
|
||||
$("#stream-view-offset-${data['session_key']}").html(millisecondsToMinutes(parseInt("${data['view_offset']}"), false));
|
||||
</script>
|
||||
</span>/<span class="progress_time" id="stream-duration-${data['session_key']}">
|
||||
<script>
|
||||
$("#stream-duration-${data['session_key']}").html(millisecondsToMinutes(parseInt("${data['duration']}"), false));
|
||||
</script>
|
||||
</span>
|
||||
</div>
|
||||
</ul>
|
||||
<ul class="list-unstyled dashboard-activity-info-list">
|
||||
<li class="dashboard-activity-info-item">
|
||||
% if _session['user_group'] == 'admin':
|
||||
<div class="sub-heading"><span class="raw-stream-info-modal" data-toggle="modal" data-target="#raw-stream-info-modal" data-key="${sk}">Stream</span></div>\
|
||||
% else:
|
||||
<div class="sub-heading">Stream</div>
|
||||
% endif
|
||||
<div class="sub-value" id="transcode_decision-${sk}">
|
||||
% if data['transcode_decision'] == 'transcode':
|
||||
Transcode
|
||||
% if data['transcode_throttled'] == '1':
|
||||
(Throttled)
|
||||
% else:
|
||||
(Speed: ${data['transcode_speed']})
|
||||
% endif
|
||||
% elif data['transcode_decision'] == 'copy':
|
||||
Direct Stream
|
||||
% else:
|
||||
Direct Play ${'(Synced)' if data['synced_version'] == '1' else ''}
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Container</div>
|
||||
<div class="sub-value" id="transcode_container-${sk}">
|
||||
% if data.get('stream_container_decision') == 'transcode':
|
||||
Transcode (${data['container'].upper()} → ${data['stream_container'].upper()})
|
||||
% else:
|
||||
Direct Play (${data['container'].upper()})
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
% if data['media_type'] in ('movie', 'episode', 'clip', 'photo'):
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Video</div>
|
||||
<div class="sub-value" id="video_decision-${sk}">
|
||||
% if data['media_type'] in ('movie', 'episode', 'clip'):
|
||||
% if data.get('stream_video_decision') == 'transcode':
|
||||
<%
|
||||
hw_d = hw_e = ''
|
||||
if data['transcode_hw_requested'] == '1' and data['transcode_hw_full_pipeline'] == '0':
|
||||
hw_d = ' (HW)'
|
||||
elif data['transcode_hw_requested'] == '1' and data['transcode_hw_full_pipeline'] == '1':
|
||||
hw_d = hw_e = ' (HW)'
|
||||
%>
|
||||
Transcode (${data['video_codec'].upper()}${hw_d} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])} → ${data['stream_video_codec'].upper()}${hw_e} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])})
|
||||
% elif data.get('stream_video_decision') == 'copy':
|
||||
Direct Stream (${data['stream_video_codec'].upper()} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['stream_video_resolution'], data['stream_video_resolution'])})
|
||||
% else:
|
||||
Direct Play (${data['video_codec'].upper()} ${plexpy.common.VIDEO_RESOLUTION_OVERRIDES.get(data['video_resolution'], data['video_resolution'])})
|
||||
% endif
|
||||
% elif data['media_type'] == 'photo':
|
||||
Direct Play (${data['width']}x${data['height']})
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
% endif
|
||||
% if data['media_type'] in ('movie', 'episode', 'clip', 'track'):
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Audio</div>
|
||||
<div class="sub-value" id="audio_decision-${sk}">
|
||||
% if data.get('stream_audio_decision') == 'transcode':
|
||||
Transcode (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()} → ${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
|
||||
% elif data.get('stream_audio_decision') == 'copy':
|
||||
Direct Stream (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
|
||||
% else:
|
||||
Direct Play (${plexpy.common.AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()})
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
% endif
|
||||
% if data['media_type'] in ('movie', 'episode', 'clip'):
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Subtitle</div>
|
||||
<div class="sub-value" id="subtitle_decision-${sk}">
|
||||
% if data['subtitles'] == '1':
|
||||
% if data['stream_subtitle_decision'] == 'transcode':
|
||||
Transcode (${data['subtitle_codec'].upper()} → ${data['stream_subtitle_codec'].upper()})
|
||||
% elif data['stream_subtitle_decision'] == 'copy':
|
||||
Direct Stream (${data['subtitle_codec'].upper()})
|
||||
% elif data['stream_subtitle_decision'] == 'burn':
|
||||
Burn (${data['subtitle_codec'].upper()})
|
||||
% else:
|
||||
Direct Play (${data['subtitle_codec'].upper()})
|
||||
% endif
|
||||
% else:
|
||||
None
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
% endif
|
||||
</ul>
|
||||
<ul class="list-unstyled dashboard-activity-info-list">
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Location</div>
|
||||
<div class="sub-value">
|
||||
% if data['ip_address'] != 'N/A':
|
||||
${'LAN' if data['local'] == '1' else 'WAN'}: ${data['ip_address']}
|
||||
<a href="#" class="external_ip-modal" data-toggle="modal" data-target="#ip-info-modal" data-ip="${data['ip_address']}">
|
||||
<span id="external_ip-${sk}" class="external-ip-tooltip" data-toggle="tooltip" title="Lookup IP" style="display: none;"><i class="fa fa-map-marker"></i></span>
|
||||
</a>
|
||||
<script>
|
||||
isPrivateIP("${data['ip_address']}").then(function () {
|
||||
$("#external_ip-${sk}").hide();
|
||||
}, function () {
|
||||
$("#external_ip-${sk}").show();
|
||||
});
|
||||
</script>
|
||||
% else:
|
||||
N/A
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
<li class="dashboard-activity-info-item">
|
||||
<div class="sub-heading">Bandwidth</div>
|
||||
<div class="sub-value">
|
||||
% if data['media_type'] != 'photo' and helpers.cast_to_int(data['bandwidth']):
|
||||
<%
|
||||
bw = helpers.cast_to_int(data['bandwidth'])
|
||||
if bw != "Unknown":
|
||||
if bw > 1000:
|
||||
bw = str(round(bw / 1000.0, 1)) + ' Mbps'
|
||||
else:
|
||||
bw = str(bw) + ' kbps'
|
||||
%>
|
||||
<span id="stream-bandwidth-${sk}">${bw}</span>
|
||||
<span id="streaming-brain-${sk}" data-toggle="tooltip" title="Streaming Brain Estimate"><i class="fa fa-info-circle"></i></span>
|
||||
% elif data['synced_version'] == '1' or data['channel_stream'] == '1':
|
||||
<span id="stream-bandwidth-${sk}">None</span>
|
||||
% else:
|
||||
<span id="stream-bandwidth-${sk}">Unknown</span>
|
||||
% endif
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
% if data['media_type'] != 'photo':
|
||||
<div class="dashboard-activity-info-time">
|
||||
% if data['view_offset']:
|
||||
ETA:
|
||||
<span id="stream-eta-${sk}">
|
||||
<script>
|
||||
$("#stream-eta-${sk}").html(moment().add(parseInt("${data['stream_duration']}") - parseInt("${data['view_offset']}"), 'milliseconds').format(time_format));
|
||||
</script>
|
||||
</span><br /><span class="progress_time_offset" id="stream-view-offset-${sk}" data-last_view_offset="${data['view_offset']}" data-view_offset="${data['view_offset']}" data-stream_duration="${data['stream_duration']}" data-state="${data['state']}">
|
||||
<script>
|
||||
$("#stream-view-offset-${sk}").html(millisecondsToMinutes(parseInt("${data['view_offset']}"), false));
|
||||
</script>
|
||||
</span> / <span class="progress_time_total" id="stream-duration-${sk}">
|
||||
<script>
|
||||
$("#stream-duration-${sk}").html(millisecondsToMinutes(parseInt("${data['stream_duration']}"), false));
|
||||
</script>
|
||||
</span>
|
||||
% else:
|
||||
ETA: Unknown<br />0:00 / <span class="progress_time_total" id="stream-duration-${sk}">
|
||||
<script>
|
||||
$("#stream-duration-${sk}").html(millisecondsToMinutes(parseInt("${data['stream_duration']}"), false));
|
||||
</script>
|
||||
</span>
|
||||
% endif
|
||||
</div>
|
||||
% if (data['media_type'] == 'movie' or data['media_type'] == 'episode' or data['media_type'] == 'track') and data['rating_key']:
|
||||
</a>
|
||||
% else:
|
||||
</a>
|
||||
% endif
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-activity-progress">
|
||||
<div class="dashboard-activity-progress-bar">
|
||||
<div id="bufferbar-${data['session_key']}" class="bufferbar" style="width: ${data['transcode_progress']}%" data-toggle="tooltip" title="Transcoder Progress ${data['transcode_progress']}%">${data['transcode_progress']}%</div>
|
||||
<div id="bar-${data['session_key']}" class="bar" style="width: ${data['progress_percent']}%" data-toggle="tooltip" title="Stream Progress ${data['progress_percent']}%">${data['progress_percent']}%</div>
|
||||
<div id="buffer-bar-${sk}" class="buffer-bar" style="width: ${data['transcode_progress']}%" data-toggle="tooltip" title="Transcoder Progress ${data['transcode_progress']}%">${data['transcode_progress']}%</div>
|
||||
<div id="progress-bar-${sk}" class="progress-bar" style="width: ${data['progress_percent']}%" data-last_view_offset="${data['view_offset']}" data-view_offset="${data['view_offset']}" data-stream_duration="${data['stream_duration']}" data-state="${data['state']}" data-toggle="tooltip" title="Stream Progress ${data['progress_percent']}%">${data['progress_percent']}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-wrapper">
|
||||
% if data['user_id']:
|
||||
<a href="user?user_id=${data['user_id']}">
|
||||
<a href="user?user_id=${data['user_id']}" title="${data['friendly_name']}">
|
||||
<div class="dashboard-activity-metadata-user-thumb" style="background-image: url(${data['user_thumb']});"></div>
|
||||
</a>
|
||||
% else:
|
||||
<div class="dashboard-activity-metadata-user-thumb" style="background-image: url(${data['user_thumb']});"></div>
|
||||
% endif
|
||||
<div class="dashboard-activity-metadata-title">
|
||||
<span id="play-state-${data['session_key']}">
|
||||
<div class="dashboard-activity-metadata-title-container">
|
||||
<div id="play-state-${sk}" class="dashboard-activity-metadata-play_state-icon" title="${data['state'].capitalize()}">
|
||||
% if data['state'] == 'playing':
|
||||
<i class="fa fa-fw fa-play"></i>
|
||||
% elif data['state'] == 'paused':
|
||||
|
@ -229,49 +356,91 @@ DOCUMENTATION :: END
|
|||
% elif data['state'] == 'buffering':
|
||||
<i class="fa fa-fw fa-spinner"></i>
|
||||
% endif
|
||||
</span>
|
||||
% if data['rating_key']:
|
||||
% if data['media_type'] == 'episode':
|
||||
<a href="info?rating_key=${data['grandparent_rating_key']}" title="${data['grandparent_title']}">${data['grandparent_title']}</a>
|
||||
- <a href="info?rating_key=${data['rating_key']}" title="${data['title']}">${data['title']}</a>
|
||||
% elif data['media_type'] == 'movie':
|
||||
<a href="info?rating_key=${data['rating_key']}" title="${data['title']}">${data['title']}</a>
|
||||
% elif data['media_type'] == 'clip':
|
||||
<span title="${data['title']}">${data['title']}</span>
|
||||
% elif data['media_type'] == 'track':
|
||||
<a href="info?rating_key=${data['grandparent_rating_key']}" title="${data['grandparent_title']}">${data['grandparent_title']}</a>
|
||||
- <a href="info?rating_key=${data['rating_key']}" title="${data['title']}">${data['title']}</a>
|
||||
% elif data['media_type'] == 'photo':
|
||||
<span title="${data['parent_title']}">${data['parent_title']}</span>
|
||||
% else:
|
||||
<span title="${data['title']}">${data['title']}</span>
|
||||
% endif
|
||||
% else:
|
||||
${data['title']}
|
||||
% endif
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-title">
|
||||
% if data['channel_stream'] == '0':
|
||||
% if data['media_type'] == 'movie':
|
||||
<a href="info?rating_key=${data['rating_key']}" title="${data['title']}">${data['title']}</a>
|
||||
% elif data['media_type'] == 'episode':
|
||||
<a href="info?rating_key=${data['grandparent_rating_key']}" title="${data['grandparent_title']}">${data['grandparent_title']}</a>
|
||||
- <a href="info?rating_key=${data['rating_key']}" title="${data['title']}">${data['title']}</a>
|
||||
% elif data['media_type'] == 'track':
|
||||
<a id="metadata-grandparent_title-${sk}" href="info?rating_key=${data['grandparent_rating_key']}" title="${data['grandparent_title']}">${data['grandparent_title']}</a>
|
||||
- <a id="metadata-title-${sk}" href="info?rating_key=${data['rating_key']}" title="${data['title']}">${data['title']}</a>
|
||||
% elif data['media_type'] == 'photo':
|
||||
<span title="${data['parent_title']}">${data['parent_title']}</span>
|
||||
% elif data['media_type'] == 'clip':
|
||||
<span title="${data['title']}">${data['title']}</span>
|
||||
% else:
|
||||
<span title="${data['title']}">${data['title']}</span>
|
||||
% endif
|
||||
% elif data['media_type'] == 'episode' and data['grandparent_title']:
|
||||
<span title="${data['grandparent_title']}">${data['grandparent_title']}</span>
|
||||
- <span title="${data['title']}">${data['title']}</span>
|
||||
% else:
|
||||
<span title="${data['title']}">${data['title']}</span>
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-subtitle">
|
||||
% if data['rating_key']:
|
||||
% if data['media_type'] == 'episode':
|
||||
<a href="info?rating_key=${data['parent_rating_key']}" title="Season ${data['parent_media_index']}" class="text-muted">S${data['parent_media_index']}</a>
|
||||
· <a href="info?rating_key=${data['rating_key']}" title="Episode ${data['media_index']}" class="text-muted">E${data['media_index']}</a>
|
||||
% elif data['media_type'] == 'movie':
|
||||
<span title="${data['year']}">${data['year']}</span>
|
||||
% elif data['media_type'] == 'track':
|
||||
<a href="info?rating_key=${data['parent_rating_key']}" title="${data['parent_title']}">${data['parent_title']}</a>
|
||||
% elif data['media_type'] == 'photo':
|
||||
<span title="${data['title']}">${data['title']}</span>
|
||||
<div class="dashboard-activity-metadata-subtitle-container">
|
||||
% if data['channel_stream'] == '0':
|
||||
<div id="media-type-${sk}" class="dashboard-activity-metadata-media_type-icon" title="${data['media_type'].capitalize()}">
|
||||
% if data['media_type'] == 'movie':
|
||||
<i class="fa fa-fw fa-film"></i>
|
||||
% elif data['media_type'] == 'episode':
|
||||
<i class="fa fa-fw fa-television"></i>
|
||||
% elif data['media_type'] == 'track':
|
||||
<i class="fa fa-fw fa-music"></i>
|
||||
% elif data['media_type'] == 'photo':
|
||||
<i class="fa fa-fw fa-picture-o"></i>
|
||||
% elif data['media_type'] == 'clip':
|
||||
<i class="fa fa-fw fa-video-camera"></i>
|
||||
% endif
|
||||
</div>
|
||||
% else:
|
||||
<span title="${data['year']}">${data['year']}</span>
|
||||
% endif
|
||||
% endif
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-user">
|
||||
% if data['user_id']:
|
||||
<a href="user?user_id=${data['user_id']}" title="${data['friendly_name']}">${data['friendly_name']}</a>
|
||||
% else:
|
||||
${data['friendly_name']}
|
||||
<div id="media-type-${sk}" title="Channel">
|
||||
<i class="fa fa-fw fa-cloud"></i>
|
||||
</div>
|
||||
% endif
|
||||
<div class="dashboard-activity-metadata-subtitle">
|
||||
% if data['channel_stream'] == '0':
|
||||
% if data['media_type'] == 'movie':
|
||||
<span title="${data['year']}" class="sub-heading">${data['year']}</span>
|
||||
% elif data['media_type'] == 'episode':
|
||||
<a href="info?rating_key=${data['parent_rating_key']}" title="Season ${data['parent_media_index']}" class="sub-heading">S${data['parent_media_index']}</a>
|
||||
· <a href="info?rating_key=${data['rating_key']}" title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</a>
|
||||
% elif data['media_type'] == 'track':
|
||||
<a id="metadata-parent_title-${sk}" href="info?rating_key=${data['parent_rating_key']}" title="${data['parent_title']}" class="sub-heading">${data['parent_title']}</a>
|
||||
% elif data['media_type'] == 'photo':
|
||||
<span title="${data['title']}" class="sub-heading">${data['title']}</span>
|
||||
% else:
|
||||
<span title="${data['year']}" class="sub-heading">${data['year']}</span>
|
||||
% endif
|
||||
% elif data['channel_title']:
|
||||
<span title="${data['channel_title']}" class="sub-heading">${data['channel_title']}</span>
|
||||
% if data['media_type'] == 'episode' and data['parent_media_index'] and data['media_index']:
|
||||
(<span title="Season ${data['parent_media_index']}" class="sub-heading">S${data['parent_media_index']}</span>
|
||||
· <span title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</span>)
|
||||
% elif data['media_type'] == 'episode' and data['originally_available_at']:
|
||||
(<span title="${data['originally_available_at']}" class="sub-heading">${data['originally_available_at']}</span>)
|
||||
% endif
|
||||
% else:
|
||||
<span title="Channel" class="sub-heading">Channel</span>
|
||||
% if data['media_type'] == 'episode' and data['parent_media_index'] and data['media_index']:
|
||||
(<span title="Season ${data['parent_media_index']}" class="sub-heading">S${data['parent_media_index']}</span>
|
||||
· <span title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</span>)
|
||||
% elif data['media_type'] == 'episode' and data['originally_available_at']:
|
||||
(<span title="${data['originally_available_at']}" class="sub-heading">${data['originally_available_at']}</span>)
|
||||
% endif
|
||||
% endif
|
||||
</div>
|
||||
<div class="dashboard-activity-metadata-user">
|
||||
% if data['user_id']:
|
||||
<a href="user?user_id=${data['user_id']}" title="${data['friendly_name']}">${data['friendly_name']}</a>
|
||||
% else:
|
||||
${data['friendly_name']}
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -45,7 +45,7 @@ DOCUMENTATION :: END
|
|||
<input type="text" class="form-control" id="custom_thumb_url" name="custom_thumb_url" value="${data['library_thumb']}">
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">Change the library's picture in PlexPy. To reset to default, leave this field empty and save.</p>
|
||||
<p class="help-block">Change the library's picture in Tautulli. To reset to default, leave this field empty and save.</p>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
|
@ -81,24 +81,6 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirm-modal-purge" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal-purge">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">Confirm Purge</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center;">
|
||||
<p>Are you REALLY sure you want to purge all history for this library?</p>
|
||||
<p>This is permanent and cannot be undone!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-purge">Purge</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Save library options
|
||||
$("#save_library").on('click', function () {
|
||||
|
@ -133,47 +115,19 @@ DOCUMENTATION :: END
|
|||
});
|
||||
});
|
||||
|
||||
$("#delete-all-history").on('click', function() {
|
||||
$('#confirm-modal-purge').modal();
|
||||
$('#confirm-modal-purge').one('click', '#confirm-purge', function () {
|
||||
$.ajax({
|
||||
url: 'delete_all_library_history',
|
||||
data: { section_id: '${data["section_id"]}' },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function(data) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#delete-all-history').click(function () {
|
||||
var msg = 'Are you REALLY sure you want to purge all history for the <strong>${data["section_name"]}</strong> library?<br>' +
|
||||
'This is permanent and cannot be undone!';
|
||||
var url = 'delete_all_library_history';
|
||||
confirmAjaxCall(url, msg, { section_id: '${data["section_id"]}' }, null, function () { location.reload(); });
|
||||
});
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
// Move #confirm-modal to parent container
|
||||
if (!($('#edit-library-modal').next().is('#confirm-modal-purge'))) {
|
||||
$('#confirm-modal-purge').appendTo($('#edit-library-modal').parent());
|
||||
}
|
||||
$('#edit-library-modal > #confirm-modal-purge').remove();
|
||||
|
||||
$('#edit-library-modal').css('z-index', '1050');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1049');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
|
||||
$('#confirm-modal-purge').on('show.bs.modal', function () {
|
||||
// Fix position to match parent modal
|
||||
var currentPadding = parseInt($('body').css('padding-right'));
|
||||
$(this).children('.modal-dialog').css('left', -currentPadding/2);
|
||||
$('#edit-library-modal').css('overflow-y', 'hidden');
|
||||
});
|
||||
$('#confirm-modal-purge').on('shown.bs.modal', function () {
|
||||
$(this).css('z-index', '1060');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1059');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
});
|
||||
$('#confirm-modal-purge').on('hidden.bs.modal', function () {
|
||||
$('body').addClass('modal-open');
|
||||
$('#edit-library-modal').css('overflow-y', 'auto');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
% endif
|
|
@ -54,7 +54,7 @@ DOCUMENTATION :: END
|
|||
<input type="text" class="form-control" id="custom_avatar_url" name="custom_avatar_url" value="${data['user_thumb']}">
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">Change the users profile picture in PlexPy. To reset to default, leave this field empty and save.</p>
|
||||
<p class="help-block">Change the users profile picture in Tautulli. To reset to default, leave this field empty and save.</p>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
|
@ -72,7 +72,7 @@ DOCUMENTATION :: END
|
|||
<label>
|
||||
<input type="checkbox" id="allow_guest" name="allow_guest" value="1" ${helpers.checked(data['allow_guest'])}> Allow Guest Access
|
||||
</label>
|
||||
<p class="help-block">Uncheck this if you do not want to allow this user to login to PlexPy.</p>
|
||||
<p class="help-block">Uncheck this if you do not want to allow this user to login to Tautulli.</p>
|
||||
</div>
|
||||
% if data['user_id']:
|
||||
<div class="form-group">
|
||||
|
@ -90,28 +90,10 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirm-modal-purge" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal-purge">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">Confirm Purge</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center;">
|
||||
<p>Are you REALLY sure you want to purge all history for this user?</p>
|
||||
<p>This is permanent and cannot be undone!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-purge">Purge</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Set user options
|
||||
$("#save_user").on('click', function () {
|
||||
var friendly_name = $("#friendly_name").val();
|
||||
var friendly_name = $("input#friendly_name").val();
|
||||
var custom_thumb = $("#custom_avatar_url").val();
|
||||
var do_notify = 0;
|
||||
var keep_history = 0;
|
||||
|
@ -144,47 +126,19 @@ DOCUMENTATION :: END
|
|||
});
|
||||
});
|
||||
|
||||
$("#delete-all-history").on('click', function() {
|
||||
$('#confirm-modal-purge').modal();
|
||||
$('#confirm-modal-purge').one('click', '#confirm-purge', function () {
|
||||
$.ajax({
|
||||
url: 'delete_all_user_history',
|
||||
data: { user_id: '${data["user_id"]}' },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function(data) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#delete-all-history').click(function () {
|
||||
var msg = 'Are you REALLY sure you want to purge all history for the <strong>${data["username"]}</strong> user?<br>' +
|
||||
'This is permanent and cannot be undone!';
|
||||
var url = 'delete_all_user_history';
|
||||
confirmAjaxCall(url, msg, { user_id: '${data["user_id"]}' }, null, function () { location.reload(); });
|
||||
});
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
// Move #confirm-modal-purge to parent container
|
||||
if (!($('#edit-user-modal').next().is('#confirm-modal-purge'))) {
|
||||
$('#confirm-modal-purge').appendTo($('#edit-user-modal').parent());
|
||||
}
|
||||
$('#edit-user-modal > #confirm-modal-purge').remove();
|
||||
|
||||
$('#edit-user-modal').css('z-index', '1050');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1049');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
|
||||
$('#confirm-modal-purge').on('show.bs.modal', function () {
|
||||
// Fix position to match parent modal
|
||||
var currentPadding = parseInt($('body').css('padding-right'));
|
||||
$(this).children('.modal-dialog').css('left', -currentPadding/2);
|
||||
$('#edit-user-modal').css('overflow-y', 'hidden');
|
||||
});
|
||||
$('#confirm-modal-purge').on('shown.bs.modal', function () {
|
||||
$(this).css('z-index', '1060');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1059');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
});
|
||||
$('#confirm-modal-purge').on('hidden.bs.modal', function () {
|
||||
$('body').addClass('modal-open');
|
||||
$('#edit-user-modal').css('overflow-y', 'auto');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
% endif
|
|
@ -20,7 +20,7 @@
|
|||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="btn-group" data-toggle="buttons" id="yaxis-selection">
|
||||
<div class="btn-group" style="margin-right: 2px;" data-toggle="buttons" id="yaxis-selection">
|
||||
% if config['graph_type'] == 'duration':
|
||||
<label class="btn btn-dark">
|
||||
<input type="radio" name="yaxis-options" id="yaxis-count" value="plays" autocomplete="off"> Play Count
|
||||
|
@ -37,15 +37,15 @@
|
|||
</label>
|
||||
% endif
|
||||
</div>
|
||||
<div class="btn-group" id="days-selection">
|
||||
<label>
|
||||
<input type="number" name="graph-days" id="graph-days" value="${config['graph_days']}" min="1" /> days
|
||||
</label>
|
||||
<div class="input-group pull-right" style="width: 1px;" id="days-selection">
|
||||
<span class="input-group-addon btn-dark inactive">Last</span>
|
||||
<input type="number" class="form-control" name="graph-days" id="graph-days" value="${config['graph_days']}" min="1" data-default="7" data-toggle="tooltip" title="Min: 1 day" />
|
||||
<span class="input-group-addon btn-dark inactive">days</span>
|
||||
</div>
|
||||
<div class="btn-group" id="months-selection">
|
||||
<label>
|
||||
<input type="number" name="graph-months" id="graph-months" value="${config['graph_months']}" min="1" /> months
|
||||
</label>
|
||||
<div class="input-group pull-right" style="width: 1px;" id="months-selection">
|
||||
<span class="input-group-addon btn-dark inactive">Last</span>
|
||||
<input type="number" class="form-control" name="graph-months" id="graph-months" value="${config['graph_months']}" min="1" data-default="12" data-toggle="tooltip" title="Min: 1 month" />
|
||||
<span class="input-group-addon btn-dark inactive">months</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -245,13 +245,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="history-modal" tabindex="-1" role="dialog" aria-labelledby="history-modal">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="modalIncludes()">
|
||||
<div class="modal fade" id="history-modal" tabindex="-1" role="dialog" aria-labelledby="history-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="info-modal" tabindex="-1" role="dialog" aria-labelledby="info-modal">
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="javascriptIncludes()">
|
||||
<script src="${http_root}js/moment-with-locale.js"></script>
|
||||
<script src="${http_root}js/moment-duration-format.js"></script>
|
||||
|
@ -287,16 +292,17 @@
|
|||
|
||||
$.ajax({
|
||||
url: "history_table_modal",
|
||||
type: 'post',
|
||||
data: {
|
||||
cache: false,
|
||||
async: true,
|
||||
data: {
|
||||
user_id: selected_user_id,
|
||||
start_date: dateString,
|
||||
media_type: media_type,
|
||||
transcode_decision: transcode_decision
|
||||
},
|
||||
complete: function(xhr, status) {
|
||||
$('#history-modal').modal('show');
|
||||
$("#history-modal").html(xhr.responseText);
|
||||
$('#history-modal').modal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -566,11 +572,7 @@
|
|||
e.preventDefault();
|
||||
current_tab = $(this).attr('href');
|
||||
loadGraphsTab1(current_day_range, yaxis);
|
||||
$.ajax({
|
||||
url: 'set_graph_config',
|
||||
data: { graph_tab: current_tab.replace('#','') },
|
||||
async: true
|
||||
});
|
||||
$.post('set_graph_config', { graph_tab: current_tab.replace('#','') });
|
||||
})
|
||||
|
||||
// Tab2 opened
|
||||
|
@ -578,11 +580,7 @@
|
|||
e.preventDefault();
|
||||
current_tab = $(this).attr('href');
|
||||
loadGraphsTab2(current_day_range, yaxis);
|
||||
$.ajax({
|
||||
url: 'set_graph_config',
|
||||
data: { graph_tab: current_tab.replace('#','') },
|
||||
async: true
|
||||
});
|
||||
$.post('set_graph_config', { graph_tab: current_tab.replace('#','') });
|
||||
})
|
||||
|
||||
// Tab3 opened
|
||||
|
@ -590,46 +588,28 @@
|
|||
e.preventDefault();
|
||||
current_tab = $(this).attr('href');
|
||||
loadGraphsTab3(current_month_range, yaxis);
|
||||
$.ajax({
|
||||
url: 'set_graph_config',
|
||||
data: { graph_tab: current_tab.replace('#','') },
|
||||
async: true
|
||||
});
|
||||
$.post('set_graph_config', { graph_tab: current_tab.replace('#','') });
|
||||
})
|
||||
|
||||
// Date range changed
|
||||
$('#graph-days').tooltip({ container: 'body', placement: 'top', html: true });
|
||||
$('#graph-days').on('change', function() {
|
||||
current_day_range = Math.round($(this).val());
|
||||
$(this).val(current_day_range);
|
||||
if (current_day_range < 1) {
|
||||
$(this).val(7);
|
||||
current_day_range = 7;
|
||||
}
|
||||
forceMinMax($(this));
|
||||
current_day_range = $(this).val();
|
||||
if (current_tab == '#tabs-1') { loadGraphsTab1(current_day_range, yaxis); }
|
||||
if (current_tab == '#tabs-2') { loadGraphsTab2(current_day_range, yaxis); }
|
||||
$('.days').html(current_day_range);
|
||||
$.ajax({
|
||||
url: 'set_graph_config',
|
||||
data: { graph_days: current_day_range},
|
||||
async: true
|
||||
});
|
||||
$.post('set_graph_config', { graph_days: current_day_range });
|
||||
});
|
||||
|
||||
// Month range changed
|
||||
$('#graph-months').tooltip({ container: 'body', placement: 'top', html: true });
|
||||
$('#graph-months').on('change', function() {
|
||||
current_month_range = Math.round($(this).val());
|
||||
$(this).val(current_month_range);
|
||||
if (current_month_range < 1) {
|
||||
$(this).val(12);
|
||||
current_month_range = 12;
|
||||
}
|
||||
forceMinMax($(this));
|
||||
current_month_range = $(this).val();
|
||||
if (current_tab == '#tabs-3') { loadGraphsTab3(current_month_range, yaxis); }
|
||||
$('.months').html(current_month_range);
|
||||
$.ajax({
|
||||
url: 'set_graph_config',
|
||||
data: { graph_months: current_month_range},
|
||||
async: true
|
||||
});
|
||||
$.post('set_graph_config', { graph_months: current_month_range });
|
||||
});
|
||||
|
||||
// User changed
|
||||
|
@ -646,11 +626,7 @@
|
|||
if (current_tab == '#tabs-1') { loadGraphsTab1(current_day_range, yaxis); }
|
||||
if (current_tab == '#tabs-2') { loadGraphsTab2(current_day_range, yaxis); }
|
||||
if (current_tab == '#tabs-3') { loadGraphsTab3(current_month_range, yaxis); }
|
||||
$.ajax({
|
||||
url: 'set_graph_config',
|
||||
data: { graph_type: yaxis},
|
||||
async: true
|
||||
});
|
||||
$.post('set_graph_config', { graph_type: yaxis });
|
||||
});
|
||||
|
||||
function setGraphFormat(type) {
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
<input type="radio" name="media_type-filter" id="history-music" value="track" autocomplete="off"> Music
|
||||
</label>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-dark refresh-history-button" id="refresh-history-list"><i class="fa fa-refresh"></i> Refresh history</button>
|
||||
</div>
|
||||
<div class="btn-group colvis-button-bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -53,7 +56,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th align="left" id="delete_row">Delete</th>
|
||||
<th align="left" id="time">Time</th>
|
||||
<th align="left" id="date">Date</th>
|
||||
<th align="left" id="friendly_name">User</th>
|
||||
<th align="left" id="ip_address">IP Address</th>
|
||||
<th align="left" id="platform">Platform</th>
|
||||
|
@ -69,26 +72,29 @@
|
|||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="modal fade" id="info-modal" tabindex="-1" role="dialog" aria-labelledby="info-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="ip-info-modal" tabindex="-1" role="dialog" aria-labelledby="ip-info-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="confirm-modal-delete" tabindex="-1" role="dialog" aria-labelledby="confirm-modal-delete">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">Confirm Delete</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center;">
|
||||
<p>Are you REALLY sure you want to delete <strong><span id="deleteCount"></span></strong> history item(s)?</p>
|
||||
<p>This is permanent and cannot be undone!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-delete">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="modalIncludes()">
|
||||
<div class="modal fade" id="info-modal" tabindex="-1" role="dialog" aria-labelledby="info-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="ip-info-modal" tabindex="-1" role="dialog" aria-labelledby="ip-info-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="confirm-modal-delete" tabindex="-1" role="dialog" aria-labelledby="confirm-modal-delete">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">Confirm Delete</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center;">
|
||||
<p>Are you REALLY sure you want to delete <strong><span id="deleteCount"></span></strong> history item(s)?</p>
|
||||
<p>This is permanent and cannot be undone!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-delete">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -101,7 +107,7 @@
|
|||
<script src="${http_root}js/dataTables.bootstrap.min.js"></script>
|
||||
<script src="${http_root}js/dataTables.bootstrap.pagination.js"></script>
|
||||
<script src="${http_root}js/moment-with-locale.js"></script>
|
||||
<script src="${http_root}js/tables/history_table.js"></script>
|
||||
<script src="${http_root}js/tables/history_table.js${cache_param}"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// Load user ids and names (for the selector)
|
||||
|
@ -166,17 +172,18 @@
|
|||
$('#deleteCount').text(history_to_delete.length);
|
||||
$('#confirm-modal-delete').modal();
|
||||
$('#confirm-modal-delete').one('click', '#confirm-delete', function () {
|
||||
for (var i = 0; i < history_to_delete.length; i++) {
|
||||
history_to_delete.forEach(function(row, idx) {
|
||||
$.ajax({
|
||||
url: 'delete_history_rows',
|
||||
data: { row_id: history_to_delete[i] },
|
||||
type: 'POST',
|
||||
data: { row_id: row },
|
||||
async: true,
|
||||
success: function (data) {
|
||||
var msg = "History deleted";
|
||||
showMsg(msg, false, true, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
history_table.draw();
|
||||
});
|
||||
}
|
||||
|
@ -196,5 +203,9 @@
|
|||
});
|
||||
% endif
|
||||
});
|
||||
|
||||
$("#refresh-history-list").click(function() {
|
||||
history_table.draw();
|
||||
});
|
||||
</script>
|
||||
</%def>
|
||||
|
|
|
@ -27,9 +27,8 @@
|
|||
<div class="modal-footer"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="info-modal" tabindex="-1" role="dialog" aria-labelledby="info-modal">
|
||||
</div>
|
||||
<script src="${http_root}js/tables/history_table_modal.js"></script>
|
||||
|
||||
<script src="${http_root}js/tables/history_table_modal.js${cache_param}"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#date-header').html(moment('${data["start_date"]}','YYYY-MM-DD').format('ddd MMM Do YYYY'));
|
||||
|
@ -44,39 +43,13 @@
|
|||
start_date: "${data['start_date']}",
|
||||
media_type: "${data.get('media_type')}",
|
||||
transcode_decision: "${data.get('transcode_decision')}"
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
history_table = $('#history_table_modal').DataTable(history_table_modal_options);
|
||||
|
||||
clearSearchButton('history_table_modal', history_table);
|
||||
|
||||
// Move #info-modal to parent container
|
||||
if (!($('#history-modal').next().is('#info-modal'))) {
|
||||
$('#info-modal').appendTo($('#history-modal').parent());
|
||||
}
|
||||
$('#history-modal > #info-modal').remove();
|
||||
|
||||
$('#history-modal').css('z-index', '1050');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1049');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
|
||||
$('#info-modal').on('show.bs.modal', function () {
|
||||
// Fix position to match parent modal
|
||||
var currentPadding = parseInt($('body').css('padding-right'));
|
||||
$(this).children('.modal-dialog').css('left', -currentPadding / 2);
|
||||
$('#history-modal').css('overflow-y', 'hidden');
|
||||
setTimeout(function () {
|
||||
$('#info-modal').css('z-index', '1060');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1059');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
}, 0);
|
||||
});
|
||||
$('#info-modal').on('hidden.bs.modal', function () {
|
||||
$('body').addClass('modal-open');
|
||||
$('#history-modal').css('overflow-y', 'auto');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
% else:
|
||||
|
|
BIN
data/interfaces/default/images/en-play-badge.png
Normal file
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 3 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 4 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 11 KiB |
BIN
data/interfaces/default/images/favicon/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
data/interfaces/default/images/favicon/favicon-16x16.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
data/interfaces/default/images/favicon/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
data/interfaces/default/images/favicon/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
data/interfaces/default/images/favicon/mstile-144x144.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
data/interfaces/default/images/favicon/mstile-150x150.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
data/interfaces/default/images/favicon/mstile-310x310.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
data/interfaces/default/images/favicon/mstile-70x70.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
70
data/interfaces/default/images/favicon/safari-pinned-tab.svg
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="275.000000pt" height="275.000000pt" viewBox="0 0 275.000000 275.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,275.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M2200 2569 c0 -4 -12 -11 -27 -17 -57 -20 -143 -130 -149 -187 -7
|
||||
-82 -6 -105 6 -140 7 -22 23 -56 36 -75 13 -19 20 -37 16 -40 -5 -3 -11 -13
|
||||
-15 -23 -4 -11 -12 -15 -19 -11 -7 4 -10 4 -6 -1 10 -11 -20 -65 -37 -65 -8 0
|
||||
-12 -6 -9 -14 3 -7 -2 -16 -11 -20 -9 -3 -14 -10 -11 -15 4 -5 -5 -18 -19 -30
|
||||
-15 -11 -26 -23 -27 -28 0 -4 -4 -7 -9 -6 -4 2 -6 -3 -4 -10 3 -6 -6 -24 -20
|
||||
-39 -14 -16 -23 -28 -20 -28 4 0 0 -7 -7 -15 -30 -33 -38 -45 -38 -55 0 -5 -4
|
||||
-10 -8 -10 -5 0 -17 -16 -28 -35 -10 -19 -22 -35 -26 -35 -5 0 -8 -5 -8 -10 0
|
||||
-10 -8 -22 -37 -55 -7 -7 -13 -17 -13 -22 0 -5 -13 -23 -30 -41 -16 -18 -31
|
||||
-36 -32 -40 -2 -4 -6 -6 -10 -5 -4 2 -4 -5 -1 -14 4 -10 2 -14 -4 -10 -6 4
|
||||
-13 -3 -17 -16 -3 -12 -16 -34 -30 -48 -14 -15 -22 -29 -19 -33 3 -3 -2 -8
|
||||
-11 -12 -9 -3 -16 -12 -16 -19 0 -6 -11 -24 -25 -39 -13 -14 -24 -30 -24 -33
|
||||
0 -4 -5 -9 -12 -12 -6 -2 -9 1 -6 6 3 5 -2 9 -12 8 -10 0 -45 2 -79 5 -34 3
|
||||
-62 2 -62 -2 0 -4 -7 -8 -15 -8 -21 0 -95 -33 -95 -43 0 -4 -5 -5 -12 -1 -7 5
|
||||
-8 3 -4 -5 5 -8 0 -14 -13 -18 -11 -3 -18 -9 -15 -14 3 -5 1 -9 -4 -9 -8 0
|
||||
-43 -60 -48 -82 -1 -5 -3 -10 -4 -13 -1 -3 -4 -9 -5 -15 -1 -5 -4 -13 -5 -17
|
||||
-1 -5 -1 -17 0 -28 1 -16 -5 -13 -28 15 -17 19 -28 38 -25 43 2 4 1 6 -4 5
|
||||
-14 -5 -114 112 -107 124 4 6 3 8 -3 5 -5 -3 -44 33 -85 81 -42 48 -90 103
|
||||
-107 122 -55 61 -72 88 -61 95 34 21 50 139 30 210 -6 22 -12 48 -13 57 -1 9
|
||||
-5 14 -9 12 -4 -3 -8 -2 -8 3 0 17 -70 84 -110 104 -26 14 -67 24 -110 27 -57
|
||||
4 -76 1 -121 -20 -30 -14 -67 -38 -83 -54 -33 -34 -70 -84 -61 -84 3 0 -1 -10
|
||||
-9 -22 -23 -37 -18 -147 8 -205 61 -130 212 -195 343 -149 38 13 41 13 59 -7
|
||||
10 -12 17 -23 15 -25 -1 -2 8 -13 21 -24 13 -11 22 -25 20 -32 -2 -6 -1 -8 3
|
||||
-4 7 7 35 -15 35 -27 0 -4 14 -20 30 -35 17 -15 30 -32 30 -38 0 -5 7 -13 16
|
||||
-16 8 -3 12 -11 8 -17 -4 -7 -3 -9 3 -6 11 7 49 -42 45 -56 -1 -5 1 -6 6 -3 8
|
||||
5 49 -35 43 -43 -1 -2 4 -8 13 -13 9 -5 13 -14 10 -20 -4 -6 -3 -8 3 -5 11 7
|
||||
45 -28 36 -37 -4 -3 2 -6 12 -6 10 0 15 -3 12 -6 -4 -4 4 -16 17 -28 13 -12
|
||||
31 -33 40 -47 15 -24 15 -27 0 -33 -8 -3 -21 -3 -26 1 -7 3 -8 1 -4 -5 4 -7
|
||||
-2 -16 -16 -22 -13 -6 -43 -24 -68 -40 -25 -16 -56 -35 -70 -42 -14 -7 -28
|
||||
-17 -31 -22 -4 -5 -12 -5 -19 -1 -9 5 -11 4 -6 -3 4 -7 3 -12 -1 -12 -5 0 -33
|
||||
-16 -63 -35 -61 -40 -63 -40 -82 -22 -7 8 -24 19 -36 26 -12 7 -20 17 -16 23
|
||||
4 7 3 8 -4 4 -6 -4 -31 -2 -54 5 -49 14 -128 18 -128 7 0 -5 -7 -8 -16 -8 -28
|
||||
0 -80 -30 -120 -69 -43 -43 -65 -68 -64 -76 1 -27 -1 -35 -9 -31 -5 3 -8 -32
|
||||
-7 -82 2 -128 46 -201 155 -256 96 -49 228 -27 309 52 17 16 34 27 37 24 4 -4
|
||||
5 -2 4 3 -4 15 11 56 20 51 6 -4 11 18 14 62 0 6 4 12 8 12 4 0 5 8 3 18 -2 9
|
||||
-5 36 -7 59 -4 40 -2 44 32 65 20 12 39 21 44 20 4 -1 7 3 7 9 0 6 7 8 17 5
|
||||
10 -4 14 -4 11 0 -6 5 54 54 67 54 2 0 24 14 49 31 25 17 51 27 57 23 8 -4 9
|
||||
-3 5 5 -4 6 0 14 11 18 10 3 30 14 44 24 14 10 29 16 33 12 3 -3 6 -1 6 5 0 7
|
||||
7 12 15 12 8 0 15 -7 15 -15 0 -8 -5 -15 -12 -15 -6 0 -9 -2 -6 -5 3 -3 0 -24
|
||||
-6 -47 -7 -23 -10 -59 -6 -83 4 -23 6 -52 5 -63 -1 -12 2 -19 6 -17 3 3 13
|
||||
-10 20 -28 19 -47 95 -113 152 -131 123 -40 255 4 319 106 22 36 45 44 60 23
|
||||
5 -6 8 -5 8 2 0 9 7 10 24 3 13 -5 44 -11 67 -15 24 -3 76 -12 114 -19 39 -8
|
||||
86 -17 106 -20 33 -6 38 -11 44 -43 12 -67 50 -124 113 -176 12 -9 26 -17 30
|
||||
-17 4 0 19 -6 34 -14 15 -8 56 -14 95 -14 245 0 365 295 190 468 -31 31 -64
|
||||
53 -92 61 -24 7 -42 15 -40 18 2 4 -20 5 -48 4 -29 -1 -52 -2 -52 -3 0 -1 -10
|
||||
-3 -23 -6 -61 -11 -182 -105 -182 -141 0 -9 -8 -12 -22 -8 -26 5 -184 33 -238
|
||||
41 -19 3 -42 8 -50 11 -15 6 -35 10 -70 12 -14 1 -20 8 -20 26 0 29 -39 115
|
||||
-60 132 -12 10 -13 15 -2 30 24 34 61 117 56 125 -3 4 0 8 6 8 6 0 9 4 6 8 -3
|
||||
5 -6 34 -7 65 -1 31 -6 57 -11 57 -4 0 -8 7 -8 16 0 9 -9 29 -21 45 -17 24
|
||||
-18 33 -9 44 7 8 16 12 21 9 5 -3 6 2 3 10 -3 9 -1 16 5 16 6 0 10 6 8 13 -1
|
||||
6 4 11 11 9 8 -1 11 1 8 6 -7 12 39 74 48 65 4 -4 4 0 0 10 -3 10 -1 17 5 17
|
||||
6 0 11 7 11 15 0 8 7 15 15 15 8 0 14 3 13 8 -3 10 110 180 199 297 5 6 26 36
|
||||
47 67 21 32 43 55 47 52 5 -3 6 1 4 8 -3 8 3 23 13 34 11 11 30 36 43 56 13
|
||||
19 40 58 59 86 l35 52 45 -7 c25 -3 50 -6 55 -6 78 5 153 38 199 87 68 72 96
|
||||
198 63 279 -9 20 -14 37 -11 37 5 0 -43 55 -76 86 -14 13 -28 24 -33 24 -4 0
|
||||
-5 5 -1 12 4 7 3 8 -4 4 -6 -4 -24 0 -40 8 -28 15 -192 19 -192 5z"/>
|
||||
<path d="M2046 2132 c-3 -5 1 -9 9 -9 8 0 12 4 9 9 -3 4 -7 8 -9 8 -2 0 -6 -4
|
||||
-9 -8z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 9.4 KiB |
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="483.904px" height="409.539px" viewBox="66.712 194.513 483.904 409.539"
|
||||
enable-background="new 66.712 194.513 483.904 409.539" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path fill="none" d="M41.209,627.586c0-151.979,0-303.963,0-456.118c177.822,0,355.688,0,533.881,0c0,151.922,0,304.021,0,456.118
|
||||
C397.214,627.586,219.233,627.586,41.209,627.586z M461.314,421.571c-110.652,0-220.389,0-329.873,0c0,18.87,0,36.226,0,54.729
|
||||
c110.29,0,219.734,0,329.824,0c0,6.858-0.271,12.563,0.058,18.231c0.659,11.344,8.853,15.958,18.112,9.46
|
||||
c22.087-15.499,43.824-31.503,65.474-47.611c7.678-5.715,7.621-10.63-0.234-16.467c-21.352-15.862-42.87-31.508-64.563-46.902
|
||||
c-9.542-6.773-17.488-2.864-18.691,8.976C460.813,407.959,461.314,414.046,461.314,421.571z M130.996,574.741
|
||||
c74.536,0,148.057,0,222.423,0c0,6.464-0.617,11.836,0.192,16.98c0.662,4.21,2.17,10.746,4.826,11.622
|
||||
c4.329,1.427,10.994,0.66,14.77-1.943c21.297-14.688,42.098-30.1,62.911-45.474c8.887-6.564,8.992-11.503,0.233-18.001
|
||||
c-20.777-15.419-41.647-30.727-62.83-45.579c-3.569-2.503-10.381-4.832-13.03-3.118c-3.676,2.376-5.784,8.447-6.81,13.308
|
||||
c-1.126,5.336-0.257,11.091-0.257,17.757c-75.009,0-148.525,0-222.43,0C130.996,538.558,130.996,555.663,130.996,574.741z
|
||||
M130.83,281.392c49.453,0,97.705,0,146.88,0c0,6.838-0.232,12.506,0.049,18.148c0.585,11.758,9.078,16.246,18.887,9.342
|
||||
c21.767-15.316,43.232-31.064,64.624-46.902c8.01-5.932,7.995-11.301-0.134-17.342c-21.053-15.65-42.257-31.103-63.625-46.318
|
||||
c-10.735-7.647-18.836-3.478-19.734,9.846c-0.378,5.611-0.063,11.27-0.063,18.431c-49.546,0-98.1,0-146.885,0
|
||||
C130.83,245.229,130.83,262.325,130.83,281.392z M188.205,379.701c0,6.939-0.606,12.297,0.19,17.438
|
||||
c0.649,4.198,2.088,10.688,4.753,11.61c4.316,1.496,11.054,0.904,14.8-1.673c21.612-14.857,42.736-30.435,63.834-46.026
|
||||
c8.481-6.265,8.471-11.812-0.159-18.227c-21.054-15.647-42.241-31.123-63.625-46.315c-10.656-7.571-18.899-3.211-19.724,10.07
|
||||
c-0.365,5.875-0.062,11.793-0.062,18.885c-20.45,0-38.938,0-57.202,0c0,18.619,0,35.973,0,54.238
|
||||
C149.953,379.701,168.131,379.701,188.205,379.701z M66.712,280.18c17.568,0,33.699,0,49.59,0c0-18.261,0-35.579,0-53.046
|
||||
c-16.925,0-33.07,0-49.59,0C66.712,245.159,66.712,262.481,66.712,280.18z M66.869,325.488c0,18.556,0,35.876,0,53.543
|
||||
c16.862,0,33,0,49.278,0c0-18.274,0-35.852,0-53.543C99.359,325.488,83.5,325.488,66.869,325.488z M116.673,422.747
|
||||
c-17.484,0-33.644,0-49.668,0c0,17.835,0,34.781,0,51.779c17.017,0,33.178,0,49.668,0
|
||||
C116.673,456.924,116.673,440.208,116.673,422.747z M116.497,520.842c-17.01,0-33.43,0-49.552,0c0,18.244,0,35.566,0,53.021
|
||||
c16.944,0,33.084,0,49.552,0C116.497,555.793,116.497,538.471,116.497,520.842z"/>
|
||||
<path fill="#FFFFFF" d="M461.314,421.571c0-7.525-0.503-13.612,0.105-19.586c1.203-11.839,9.149-15.749,18.691-8.976
|
||||
c21.691,15.396,43.211,31.04,64.563,46.902c7.855,5.837,7.912,10.752,0.234,16.467c-21.648,16.108-43.387,32.112-65.474,47.611
|
||||
c-9.261,6.498-17.453,1.884-18.112-9.46c-0.329-5.67-0.058-11.373-0.058-18.231c-110.09,0-219.534,0-329.824,0
|
||||
c0-18.503,0-35.857,0-54.729C240.927,421.571,350.662,421.571,461.314,421.571z"/>
|
||||
<path fill="#FFFFFF" d="M130.996,574.741c0-19.078,0-36.185,0-54.448c73.904,0,147.42,0,222.43,0
|
||||
c0-6.666-0.869-12.421,0.257-17.757c1.024-4.859,3.134-10.932,6.81-13.308c2.649-1.714,9.461,0.615,13.029,3.118
|
||||
c21.184,14.854,42.054,30.16,62.831,45.579c8.759,6.498,8.652,11.437-0.233,18.001c-20.813,15.374-41.614,30.786-62.911,45.474
|
||||
c-3.774,2.604-10.439,3.369-14.77,1.943c-2.656-0.876-4.165-7.412-4.826-11.622c-0.811-5.146-0.192-10.518-0.192-16.98
|
||||
C279.053,574.741,205.532,574.741,130.996,574.741z"/>
|
||||
<path fill="#FFFFFF" d="M130.83,281.392c0-19.067,0-36.163,0-54.795c48.785,0,97.339,0,146.885,0
|
||||
c0-7.161-0.315-12.82,0.063-18.431c0.898-13.323,8.999-17.493,19.734-9.846c21.368,15.215,42.572,30.668,63.625,46.318
|
||||
c8.129,6.041,8.144,11.411,0.133,17.342c-21.391,15.838-42.855,31.586-64.623,46.902c-9.81,6.904-18.302,2.417-18.887-9.342
|
||||
c-0.281-5.643-0.049-11.31-0.049-18.148C228.535,281.392,180.283,281.392,130.83,281.392z"/>
|
||||
<path fill="#FFFFFF" d="M188.205,379.701c-20.074,0-38.252,0-57.192,0c0-18.265,0-35.619,0-54.238c18.264,0,36.752,0,57.202,0
|
||||
c0-7.092-0.303-13.01,0.062-18.885c0.825-13.281,9.067-17.641,19.724-10.07c21.383,15.193,42.57,30.668,63.625,46.315
|
||||
c8.63,6.416,8.64,11.962,0.159,18.227c-21.099,15.591-42.222,31.169-63.834,46.026c-3.746,2.577-10.484,3.169-14.8,1.673
|
||||
c-2.666-0.923-4.104-7.412-4.753-11.61C187.599,391.999,188.205,386.64,188.205,379.701z"/>
|
||||
<path fill="#FFFFFF" d="M66.712,280.18c0-17.699,0-35.021,0-53.046c16.52,0,32.665,0,49.59,0c0,17.468,0,34.786,0,53.046
|
||||
C100.411,280.18,84.281,280.18,66.712,280.18z"/>
|
||||
<path fill="#FFFFFF" d="M66.869,325.488c16.63,0,32.49,0,49.278,0c0,17.692,0,35.27,0,53.543c-16.278,0-32.416,0-49.278,0
|
||||
C66.869,361.364,66.869,344.044,66.869,325.488z"/>
|
||||
<path fill="#E5A00D" d="M116.673,422.747c0,17.461,0,34.177,0,51.779c-16.49,0-32.652,0-49.668,0c0-16.998,0-33.944,0-51.779
|
||||
C83.029,422.747,99.188,422.747,116.673,422.747z"/>
|
||||
<path fill="#FFFFFF" d="M116.497,520.842c0,17.629,0,34.951,0,53.021c-16.468,0-32.608,0-49.552,0c0-17.455,0-34.777,0-53.021
|
||||
C83.067,520.842,99.487,520.842,116.497,520.842z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.4 KiB |
5
data/interfaces/default/images/libraries/artist.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>artist</title>
|
||||
<path fill="#fff" d="M9.201 24.681c0-6.699 0-13.358 0-20.035 7.594-1.505 15.157-3.004 22.768-4.513 0 0.172 0 0.319 0 0.465 0 7.067-0.026 14.135 0.021 21.202 0.010 1.498-0.59 2.57-1.716 3.423-1.999 1.512-4.26 2.145-6.751 1.88-0.504-0.054-1.020-0.205-1.481-0.418-1.502-0.695-1.856-2.122-0.908-3.48 0.826-1.184 1.99-1.924 3.302-2.433 1.362-0.528 2.774-0.843 4.252-0.719 0.324 0.027 0.646 0.084 0.994 0.13 0-4.345 0-8.679 0-13.050-6.062 1.204-12.099 2.404-18.16 3.608 0 0.196 0 0.345 0 0.495 0 5.174-0.006 10.349 0.004 15.523 0.003 1.409-0.802 2.302-1.854 3.056-0.889 0.637-1.859 1.114-2.906 1.426-1.524 0.453-3.067 0.627-4.619 0.169-0.952-0.281-1.789-0.736-2.010-1.83-0.136-0.673 0.098-1.269 0.459-1.822 0.772-1.183 1.947-1.853 3.193-2.388 1.662-0.714 3.394-1.043 5.207-0.698 0.048 0.009 0.099 0.005 0.206 0.010z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 979 B |
5
data/interfaces/default/images/libraries/movie.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>movie</title>
|
||||
<path fill="#fff" d="M0 1.416c10.695 0 21.315 0 32 0 0 9.719 0 19.417 0 29.168-10.635 0-21.293 0-32 0 0-9.699 0-19.399 0-29.168zM9.202 15.129c4.535 0 9.065 0 13.609 0 0-3.798 0-7.579 0-11.355-4.563 0-9.075 0-13.609 0 0 3.801 0 7.551 0 11.355zM9.215 28.909c4.581 0 9.093 0 13.61 0 0-3.818 0-7.585 0-11.382-4.549 0-9.062 0-13.61 0 0 3.803 0 7.57 0 11.382zM6.813 5.983c0-0.753 0-1.467 0-2.209-1.138 0-2.235 0-3.33 0 0 0.766 0 1.48 0 2.209 1.131 0 2.21 0 3.33 0zM25.231 3.754c0 0.783 0 1.494 0 2.219 1.141 0 2.235 0 3.33 0 0-0.763 0-1.476 0-2.219-1.12 0-2.198 0-3.33 0zM25.233 12.938c0 0.777 0 1.492 0 2.19 1.149 0 2.248 0 3.335 0 0-0.754 0-1.452 0-2.19-1.116 0-2.197 0-3.335 0zM25.227 22.074c0 0.783 0 1.496 0 2.218 1.139 0 2.235 0 3.335 0 0-0.758 0-1.471 0-2.218-1.119 0-2.196 0-3.335 0zM3.472 26.689c0 0.768 0 1.481 0 2.221 1.133 0 2.226 0 3.34 0 0-0.763 0-1.475 0-2.221-1.119 0-2.197 0-3.34 0zM28.579 26.711c-1.112 0-2.225 0-3.353 0 0 0.749 0 1.462 0 2.202 1.137 0 2.233 0 3.353 0 0-0.748 0-1.447 0-2.202zM6.817 15.155c0-0.774 0-1.468 0-2.21-1.133 0-2.229 0-3.338 0 0 0.761 0 1.473 0 2.21 1.127 0 2.207 0 3.338 0zM3.463 19.73c1.165 0 2.242 0 3.346 0 0-0.759 0-1.469 0-2.189-1.143 0-2.239 0-3.346 0 0 0.748 0 1.446 0 2.189zM28.559 19.733c0-0.764 0-1.479 0-2.188-1.144 0-2.241 0-3.34 0 0 0.752 0 1.448 0 2.188 1.114 0 2.195 0 3.34 0zM6.791 24.304c0-0.798 0-1.511 0-2.215-1.145 0-2.225 0-3.312 0 0 0.766 0 1.481 0 2.215 1.129 0 2.211 0 3.312 0zM3.489 8.378c0 0.771 0 1.464 0 2.145 1.138 0 2.219 0 3.319 0 0-0.74 0-1.431 0-2.145-1.129 0-2.211 0-3.319 0zM28.554 10.538c0-0.775 0-1.464 0-2.137-1.146 0-2.242 0-3.319 0 0 0.747 0 1.438 0 2.137 1.131 0 2.21 0 3.319 0z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
6
data/interfaces/default/images/libraries/photo.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>photo</title>
|
||||
<path fill="#fff" d="M25.208 2.266c0 1.514 0 2.976 0 4.513 2.281 0 4.505 0 6.792 0 0 7.681 0 15.287 0 22.955-10.643 0-21.3 0-32 0 0-7.626 0-15.236 0-22.913 2.258 0 4.486 0 6.792 0 0-1.546 0-3.029 0-4.555 6.152 0 12.226 0 18.415 0zM16.008 9.209c-5.026-0.004-9.12 4.079-9.123 9.099-0.004 4.961 4.099 9.069 9.074 9.085 5.022 0.016 9.124-4.047 9.159-9.070 0.035-4.985-4.087-9.109-9.109-9.114z"></path>
|
||||
<path fill="#fff" d="M20.601 18.292c0.003 2.551-2.070 4.626-4.61 4.613-2.558-0.013-4.595-2.069-4.591-4.634 0.003-2.524 2.038-4.557 4.577-4.572 2.562-0.015 4.621 2.030 4.624 4.593z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 746 B |
12
data/interfaces/default/images/libraries/playlist.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>playlist</title>
|
||||
<path fill="#fff" d="M9.167 10.268c7.653 0 15.208 0 22.82 0 0 1.147 0 2.268 0 3.451-7.583 0-15.172 0-22.82 0 0-1.134 0-2.274 0-3.451z"></path>
|
||||
<path fill="#fff" d="M9.14 21.73c0-1.152 0-2.257 0-3.424 7.609 0 15.212 0 22.86 0 0 1.132 0 2.252 0 3.424-7.607 0-15.191 0-22.86 0z"></path>
|
||||
<path fill="#fff" d="M9.217 5.679c0-1.145 0-2.23 0-3.363 7.562 0 15.101 0 22.683 0 0 1.113 0 2.213 0 3.363-7.539 0-15.080 0-22.683 0z"></path>
|
||||
<path fill="#fff" d="M9.225 29.708c0-1.132 0-2.214 0-3.336 7.558 0 15.086 0 22.668 0 0 1.086 0 2.186 0 3.336-7.526 0-15.071 0-22.668 0z"></path>
|
||||
<path fill="#fff" d="M0.007 10.279c1.58 0 3.043 0 4.551 0 0 1.153 0 2.272 0 3.444-1.511 0-3.011 0-4.551 0 0-1.157 0-2.292 0-3.444z"></path>
|
||||
<path fill="#fff" d="M4.527 2.292c0 1.183 0 2.284 0 3.424-1.496 0-2.957 0-4.479 0 0-1.142 0-2.276 0-3.424 1.51 0 2.971 0 4.479 0z"></path>
|
||||
<path fill="#fff" d="M4.571 18.3c0 1.151 0 2.254 0 3.416-1.515 0-3.019 0-4.571 0 0-1.127 0-2.247 0-3.416 1.513 0 3.001 0 4.571 0z"></path>
|
||||
<path fill="#fff" d="M4.54 26.352c0 1.137 0 2.218 0 3.354-1.494 0-2.975 0-4.506 0 0-1.094 0-2.192 0-3.354 1.489 0 2.965 0 4.506 0z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
6
data/interfaces/default/images/libraries/show.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>show</title>
|
||||
<path fill="#fff" d="M0 26.565c0-8.38 0-16.706 0-25.089 10.661 0 21.307 0 32 0 0 8.343 0 16.686 0 25.089-10.637 0-21.283 0-32 0zM3.514 4.937c0 5.355 0 10.634 0 15.901 8.375 0 16.691 0 24.994 0 0-5.331 0-10.612 0-15.901-8.356 0-16.656 0-24.994 0z"></path>
|
||||
<path fill="#fff" d="M6.874 30.524c0-0.553 0-1.056 0-1.602 6.084 0 12.136 0 18.25 0 0 0.509 0 1.029 0 1.602-6.050 0-12.12 0-18.25 0z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 555 B |
5
data/interfaces/default/images/libraries/video.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!-- Generated by IcoMoon.io -->
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||
<title>video</title>
|
||||
<path fill="#fff" d="M20.662 27.439c-6.971 0-13.797 0-20.662 0 0-7.639 0-15.235 0-22.878 6.846 0 13.672 0 20.588 0 0 2.962 0 5.932 0 9.091 3.87-2.316 7.591-4.542 11.412-6.828 0 6.153 0 12.176 0 18.33-3.769-2.257-7.494-4.488-11.338-6.789 0 3.070 0 6.035 0 9.075z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 430 B |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 8.2 KiB |
BIN
data/interfaces/default/images/logo-tautulli-50.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
data/interfaces/default/images/logo-tautulli.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
data/interfaces/default/images/logo.png
Normal file
After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 5.1 KiB |
BIN
data/interfaces/default/images/media_flags/studio/aic.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 3.3 KiB |
BIN
data/interfaces/default/images/media_flags/studio/chiller.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
data/interfaces/default/images/media_flags/studio/dave.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 5.5 KiB |
BIN
data/interfaces/default/images/media_flags/studio/defa.png
Normal file
After Width: | Height: | Size: 879 B |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 3.8 KiB |
BIN
data/interfaces/default/images/media_flags/studio/emi.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
data/interfaces/default/images/media_flags/studio/epix.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
data/interfaces/default/images/media_flags/studio/freeform.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 16 KiB |
BIN
data/interfaces/default/images/media_flags/studio/konami.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 9.3 KiB |
BIN
data/interfaces/default/images/media_flags/studio/lego.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
data/interfaces/default/images/media_flags/studio/madhouse.png
Normal file
After Width: | Height: | Size: 5 KiB |
After Width: | Height: | Size: 5.5 KiB |
BIN
data/interfaces/default/images/media_flags/studio/pa_works.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
data/interfaces/default/images/media_flags/studio/pop.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 26 KiB |
BIN
data/interfaces/default/images/media_flags/studio/rte_one.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 7.7 KiB |
BIN
data/interfaces/default/images/media_flags/studio/scholastic.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
data/interfaces/default/images/media_flags/studio/seeso.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
data/interfaces/default/images/media_flags/studio/shaft.png
Normal file
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 3 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 10 KiB |