mirror of
https://github.com/gosticks/PiPer.git
synced 2025-10-16 11:55:42 +00:00
commit
786d1bcff7
@ -47,13 +47,15 @@ Install from the [Mac App Store](https://itunes.apple.com/app/id1421915518?mt=12
|
||||
### Chrome
|
||||
Install from the [Chrome Web Store](https://chrome.google.com/webstore/detail/piper/jbjleapidaddpbncgofepljddfeoghkc) by clicking "Add to Chrome"
|
||||
|
||||
<sub>...or live life on the edge with the latest [development build](https://github.com/amarcu5/PiPer/tree/develop/out) (IMPORTANT: these builds do not update automatically!)</sub>
|
||||
<sub>...or live life on the edge with the latest [development build](https://github.com/amarcu5/PiPer/tree/develop-1.0.x/out) (IMPORTANT: these builds do not update automatically!)</sub>
|
||||
|
||||
## Supported sites
|
||||
* [9Now](http://www.9now.com.au)
|
||||
* [Amazon Video](http://www.amazon.com/PrimeVideo)
|
||||
* [CollegeHumor](http://www.collegehumor.com)
|
||||
* [CuriosityStream](http://www.curiositystream.com)
|
||||
* [Eurosport player](http://www.eurosportplayer.com)
|
||||
* [FuboTV](http://www.fubo.tv)
|
||||
* [Giant Bomb](http://www.giantbomb.com)
|
||||
* [Hulu](http://www.hulu.com)
|
||||
* [LittleThings](http://www.littlethings.com)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -36,8 +36,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Test for Picture in Picture support and display warning to activate Chrome flags if needed
|
||||
const video = /** @type {HTMLVideoElement} */ (document.getElementById('test-video'));
|
||||
video.addEventListener('loadeddata', function() {
|
||||
video.requestPictureInPicture().catch(function(/** Error */ error) {
|
||||
if (~error.message.indexOf('Picture-in-Picture is not available')) {
|
||||
video.requestPictureInPicture().catch(function(error) {
|
||||
const errorMessage = /** @type {Error} */ (error).message;
|
||||
if (~errorMessage.indexOf('Picture-in-Picture is not available')) {
|
||||
info('Picture-in-Picture NOT supported');
|
||||
document.getElementById('warning').style.display = 'flex';
|
||||
} else {
|
||||
|
||||
@ -14,13 +14,13 @@ export const Browser = {
|
||||
* @return {Browser}
|
||||
*/
|
||||
export const getBrowser = function() {
|
||||
if (BROWSER != Browser.UNKNOWN) {
|
||||
if (BROWSER != Browser.UNKNOWN) {
|
||||
return /** @type {Browser} */ (BROWSER);
|
||||
}
|
||||
if (/Safari/.test(navigator.userAgent) && /Apple/.test(navigator.vendor)) {
|
||||
return Browser.SAFARI;
|
||||
}
|
||||
if (/Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor)) {
|
||||
if (/Chrome/.test(navigator.userAgent) && /Google/.test(navigator.vendor)) {
|
||||
return Browser.CHROME;
|
||||
}
|
||||
return Browser.UNKNOWN;
|
||||
|
||||
@ -78,7 +78,7 @@ const callAnimationFrameRequestsAndTimeouts = function() {
|
||||
/**
|
||||
* Avoids background throttling by invoking timeouts with media 'timeupdate' events
|
||||
*
|
||||
* @param {Function|string} callback - a setTimeout callback
|
||||
* @param {Function|TrustedScript|string} callback - a setTimeout callback
|
||||
* @param {number=} timeout - a delay in ms
|
||||
* @return {number}
|
||||
*/
|
||||
|
||||
@ -28,8 +28,23 @@ const mutationObserver = function() {
|
||||
}
|
||||
};
|
||||
|
||||
// Remove subdomain and public suffix (far from comprehensive as only removes .X and .co.Y)
|
||||
const domainName = location.hostname && location.hostname.match(/([^.]+)\.(?:co\.)?[^.]+$/)[1];
|
||||
/**
|
||||
* Returns the first non-public subdomain from the current domain name
|
||||
*
|
||||
* @return {string|undefined}
|
||||
*/
|
||||
const getCurrentDomainName = function() {
|
||||
|
||||
// Special case for local Plex Media Server access that always uses port 32400
|
||||
if (location.port == 32400) {
|
||||
return 'plex';
|
||||
} else {
|
||||
// Remove subdomain and public suffix (far from comprehensive as only removes .X and .co.Y)
|
||||
return (location.hostname.match(/([^.]+)\.(?:com?\.)?[^.]+$/) || [])[1];
|
||||
}
|
||||
};
|
||||
|
||||
const domainName = getCurrentDomainName();
|
||||
|
||||
if (domainName in resources) {
|
||||
info(`Matched site ${domainName} (${location})`);
|
||||
|
||||
30
src/common/scripts/resources/9now.js
Normal file
30
src/common/scripts/resources/9now.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { getResource } from './../common.js'
|
||||
|
||||
export const domain = '9now';
|
||||
|
||||
export const resource = {
|
||||
buttonClassName: 'vjs-control vjs-button',
|
||||
buttonHoverStyle: /** CSS */ (`
|
||||
filter: brightness(50%) sepia(1) hue-rotate(167deg) saturate(253%) brightness(104%);
|
||||
`),
|
||||
buttonInsertBefore: function(/** Element */ parent) {
|
||||
return parent.querySelector('.vjs-fullscreen-control');
|
||||
},
|
||||
buttonParent: function() {
|
||||
return document.querySelector('.vjs-control-bar');
|
||||
},
|
||||
buttonScale: 0.7,
|
||||
buttonStyle: /** CSS */ (`
|
||||
order: 999999;
|
||||
cursor: pointer;
|
||||
height: 44px;
|
||||
width: 40px;
|
||||
`),
|
||||
captionElement: function() {
|
||||
const e = getResource().videoElement();
|
||||
return e && e.parentElement.querySelector('.vjs-text-track-display');
|
||||
},
|
||||
videoElement: function() {
|
||||
return document.querySelector('video.vjs-tech');
|
||||
},
|
||||
};
|
||||
@ -1,16 +0,0 @@
|
||||
export const domain = 'collegehumor';
|
||||
|
||||
export const resource = {
|
||||
buttonClassName: 'vjs-control vjs-button',
|
||||
buttonInsertBefore: function(/** Element */ parent) {
|
||||
return parent.lastChild;
|
||||
},
|
||||
buttonParent: function() {
|
||||
return document.querySelector('.vjs-control-bar');
|
||||
},
|
||||
buttonScale: 0.6,
|
||||
buttonStyle: /** CSS */ (`cursor: pointer`),
|
||||
videoElement: function() {
|
||||
return document.getElementById('vjs_video_3_html5_api');
|
||||
},
|
||||
};
|
||||
21
src/common/scripts/resources/fubotv.js
Normal file
21
src/common/scripts/resources/fubotv.js
Normal file
@ -0,0 +1,21 @@
|
||||
export const domain = 'fubo';
|
||||
|
||||
export const resource = {
|
||||
buttonElementType: 'div',
|
||||
buttonInsertBefore: function(/** Element */ parent) {
|
||||
return parent.lastChild;
|
||||
},
|
||||
buttonParent: function() {
|
||||
return document.querySelector('.css-ja7yk7');
|
||||
},
|
||||
buttonScale: 1.25,
|
||||
buttonStyle: /** CSS */ (`
|
||||
height: 24px;
|
||||
width: 25px;
|
||||
margin: 8px 10px 12px;
|
||||
cursor: pointer;
|
||||
`),
|
||||
videoElement: function() {
|
||||
return document.getElementById('video');
|
||||
},
|
||||
};
|
||||
@ -1,21 +0,0 @@
|
||||
export const domain = 'giantbomb';
|
||||
|
||||
export const resource = {
|
||||
buttonElementType: 'div',
|
||||
buttonInsertBefore: function(/** Element */ parent) {
|
||||
return parent.querySelector('.js-vid-pin-wrap').nextSibling;
|
||||
},
|
||||
buttonParent: function() {
|
||||
return document.querySelector('.av-controls--right');
|
||||
},
|
||||
buttonScale: 0.7,
|
||||
buttonStyle: /** CSS */ (`
|
||||
margin-left: 16px;
|
||||
height: 100%;
|
||||
opacity: 1.0;
|
||||
cursor: pointer;
|
||||
`),
|
||||
videoElement: function() {
|
||||
return document.querySelector('video[id^="video_js-vid-player"]');
|
||||
}
|
||||
};
|
||||
@ -12,7 +12,7 @@ export const resource = {
|
||||
},
|
||||
buttonScale: 0.65,
|
||||
buttonStyle: /** CSS */ (`
|
||||
margin-top: 3px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
|
||||
@ -19,6 +19,6 @@ export const resource = {
|
||||
filter: brightness(200%);
|
||||
`),
|
||||
videoElement: function() {
|
||||
return document.querySelector('.vjs-tech video[src]');
|
||||
return document.querySelector('.Video video');
|
||||
},
|
||||
};
|
||||
@ -26,6 +26,10 @@ export const resource = {
|
||||
if (videoPlayingPictureInPicture(video)) togglePictureInPicture(video);
|
||||
});
|
||||
neighbourButton.style.order = 2;
|
||||
|
||||
// Ensure "Watch on Twitch" button is the rightmost button
|
||||
const twitchButton = document.querySelector('.qa-watch-twitch-button');
|
||||
if (twitchButton) twitchButton.style.order = 3;
|
||||
},
|
||||
buttonHoverStyle: /** CSS */ (`
|
||||
filter: brightness(50%) sepia(1) hue-rotate(219deg) saturate(117%) brightness(112%);
|
||||
|
||||
@ -24,7 +24,7 @@ export const resource = {
|
||||
buttonScale: 0.6,
|
||||
buttonStyle: /** CSS */ (`
|
||||
position: absolute;
|
||||
right: calc(50px + 2.5rem);
|
||||
right: 114px;
|
||||
width: 50px;
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
|
||||
@ -43,7 +43,8 @@ export const togglePictureInPicture = function(video) {
|
||||
* @param {function(HTMLVideoElement, boolean)} listener - an event listener to add
|
||||
*/
|
||||
export const addPictureInPictureEventListener = function(listener) {
|
||||
if (!eventListeners.includes(listener)) {
|
||||
const index = eventListeners.indexOf(listener);
|
||||
if (index == -1) {
|
||||
eventListeners.push(listener);
|
||||
}
|
||||
|
||||
|
||||
@ -100,11 +100,11 @@
|
||||
const currentTimestamp = Date.now();
|
||||
|
||||
let /** number */ alertInterval;
|
||||
if (currentTimestamp >= 1551398400000) { // 2019-03-01
|
||||
if (currentTimestamp >= 1556665200000) { // 2019-05-01
|
||||
alertInterval = 3.6e+6; // hourly
|
||||
} else if (currentTimestamp >= 1548979200000) { // 2019-02-01
|
||||
} else if (currentTimestamp >= 1554073200000) { // 2019-04-01
|
||||
alertInterval = 8.64e+7; // daily
|
||||
} else if (currentTimestamp >= 1546300800000) { // 2019-01-01
|
||||
} else if (currentTimestamp >= 1551398400000) { // 2019-03-01
|
||||
alertInterval = 6.048e+8; // weekly
|
||||
} else {
|
||||
alertInterval = 2.628e+9; // monthly
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.amarcus.safari.piper</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string></string>
|
||||
<string>1.0.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>191</string>
|
||||
<string>207</string>
|
||||
<key>Developer Identifier</key>
|
||||
<string>BQ6Q24MF9X</string>
|
||||
<key>URL</key>
|
||||
|
||||
@ -149,6 +149,10 @@ class DonationManager {
|
||||
let emoticons = Array({
|
||||
() -> String in
|
||||
switch Calendar.current.dateComponents([.month, .weekdayOrdinal, .weekday, .day], from: Date()) {
|
||||
case let date where date.month == 1 && date.day == 1: // New Years
|
||||
return "🕛🥂🍾🎊"
|
||||
case let date where date.month == 2 && date.day == 14: // Valentine's Day
|
||||
return "🥀🌹💋💘"
|
||||
case let date where date.month == 10 && date.day == 31: // Halloween
|
||||
return "💀👻🧙♀️🎃"
|
||||
case let date where date.month == 11 && date.weekdayOrdinal == 4 && date.weekday == 5: // Thanksgiving
|
||||
|
||||
Loading…
Reference in New Issue
Block a user