diff --git a/src/renderer/component/app/index.js b/src/renderer/component/app/index.js index 36381d580..657e6e9a6 100644 --- a/src/renderer/component/app/index.js +++ b/src/renderer/component/app/index.js @@ -7,8 +7,10 @@ import { doError, } from 'lbry-redux'; import { doRecordScroll } from 'redux/actions/navigation'; +import { doToggleEnhancedLayout } from 'redux/actions/app'; import { selectUser } from 'lbryinc'; import { selectThemePath } from 'redux/selectors/settings'; +import { selectEnhancedLayout } from 'redux/selectors/app'; import App from './view'; const select = state => ({ @@ -17,12 +19,14 @@ const select = state => ({ currentStackIndex: selectHistoryIndex(state), currentPageAttributes: selectActiveHistoryEntry(state), theme: selectThemePath(state), + enhancedLayout: selectEnhancedLayout(state), }); const perform = dispatch => ({ alertError: errorList => dispatch(doError(errorList)), recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)), updateBlockHeight: () => dispatch(doUpdateBlockHeight()), + toggleEnhancedLayout: () => dispatch(doToggleEnhancedLayout()), }); export default connect( diff --git a/src/renderer/component/app/view.jsx b/src/renderer/component/app/view.jsx index e258a7ec6..33d3465a0 100644 --- a/src/renderer/component/app/view.jsx +++ b/src/renderer/component/app/view.jsx @@ -6,7 +6,9 @@ import ReactModal from 'react-modal'; import throttle from 'util/throttle'; import SideBar from 'component/sideBar'; import Header from 'component/header'; -import { openContextMenu } from '../../util/context-menu'; +import { openContextMenu } from 'util/context-menu'; +import EnhancedLayoutListener from 'util/enhanced-layout'; +import Native from 'native'; const TWO_POINT_FIVE_MINUTES = 1000 * 60 * 2.5; @@ -18,6 +20,8 @@ type Props = { pageTitle: ?string, theme: string, updateBlockHeight: () => void, + toggleEnhancedLayout: () => void, + enhancedLayout: boolean, }; class App extends React.PureComponent { @@ -41,17 +45,18 @@ class App extends React.PureComponent { } componentDidMount() { - const { updateBlockHeight } = this.props; + const { updateBlockHeight, toggleEnhancedLayout } = this.props; const mainContent = document.getElementById('content'); this.mainContent = mainContent; - if (this.mainContent) { this.mainContent.addEventListener('scroll', throttle(this.scrollListener, 750)); } ReactModal.setAppElement('#window'); // fuck this + this.enhance = new EnhancedLayoutListener(() => toggleEnhancedLayout()); + updateBlockHeight(); setInterval(() => { updateBlockHeight(); @@ -81,6 +86,8 @@ class App extends React.PureComponent { if (this.mainContent) { this.mainContent.removeEventListener('scroll', this.scrollListener); } + + this.enhance = null; } setTitleFromProps = (title: ?string) => { @@ -96,12 +103,22 @@ class App extends React.PureComponent { } mainContent: ?HTMLElement; + enhance: ?any; render() { + const { enhancedLayout } = this.props; + return (
openContextMenu(e)}>
+ {enhancedLayout && ( + Friendly gerbil + )}
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index af47919d4..b4b09322b 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -16,6 +16,7 @@ export const VOLUME_CHANGED = 'VOLUME_CHANGED'; export const ADD_COMMENT = 'ADD_COMMENT'; export const SHOW_MODAL = 'SHOW_MODAL'; export const HIDE_MODAL = 'HIDE_MODAL'; +export const ENNNHHHAAANNNCEEE = 'ENNNHHHAAANNNCEEE'; // Navigation export const CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH'; diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js index 82f770893..89a3fbe77 100644 --- a/src/renderer/redux/actions/app.js +++ b/src/renderer/redux/actions/app.js @@ -371,3 +371,9 @@ export function doConditionalAuthNavigate(newSession) { } }; } + +export function doToggleEnhancedLayout() { + return { + type: ACTIONS.ENNNHHHAAANNNCEEE, + }; +} diff --git a/src/renderer/redux/reducers/app.js b/src/renderer/redux/reducers/app.js index f92652d07..785a25f4e 100644 --- a/src/renderer/redux/reducers/app.js +++ b/src/renderer/redux/reducers/app.js @@ -34,6 +34,7 @@ export type AppState = { isUpgradeAvailable: ?boolean, isUpgradeSkipped: ?boolean, hasClickedComment: boolean, + enhancedLayout: boolean, }; const defaultState: AppState = { @@ -57,6 +58,7 @@ const defaultState: AppState = { checkUpgradeTimer: undefined, isUpgradeAvailable: undefined, isUpgradeSkipped: undefined, + enhancedLayout: false, }; reducers[ACTIONS.DAEMON_READY] = state => @@ -213,6 +215,11 @@ reducers[ACTIONS.AUTHENTICATION_FAILURE] = state => modal: MODALS.AUTHENTICATION_FAILURE, }); +reducers[ACTIONS.ENNNHHHAAANNNCEEE] = state => + Object.assign({}, state, { + enhancedLayout: !state.enhancedLayout, + }); + export default function reducer(state: AppState = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/renderer/redux/selectors/app.js b/src/renderer/redux/selectors/app.js index 58ec2cc7e..f869e9e35 100644 --- a/src/renderer/redux/selectors/app.js +++ b/src/renderer/redux/selectors/app.js @@ -263,3 +263,5 @@ export const selectModal = createSelector(selectState, state => { modalProps: state.modalProps, }; }); + +export const selectEnhancedLayout = createSelector(selectState, state => state.enhancedLayout); diff --git a/src/renderer/scss/component/_yrbl.scss b/src/renderer/scss/component/_yrbl.scss index 7412df96e..7dba455b1 100644 --- a/src/renderer/scss/component/_yrbl.scss +++ b/src/renderer/scss/component/_yrbl.scss @@ -8,3 +8,30 @@ width: auto; margin: 0 var(--spacing-vertical-large); } + +// Get weird here +.yrbl--enhanced { + position: absolute; + z-index: 9999; + height: 95vh; + width: 95vh; + left: 0; + right: 0; + opacity: 0.5; + animation-name: enhancedAnimation; + animation-duration: 2s; + animation-iteration-count: infinite; + animation-direction: alternate; + animation-timing-function: ease-out; +} + +@-webkit-keyframes enhancedAnimation { + from { + left: 0; + transform: rotate(0deg); + } + to { + left: 50vw; + transform: rotate(360deg); + } +} diff --git a/src/renderer/util/enhanced-layout.js b/src/renderer/util/enhanced-layout.js new file mode 100644 index 000000000..20830684a --- /dev/null +++ b/src/renderer/util/enhanced-layout.js @@ -0,0 +1,152 @@ +/* eslint-disable */ +/* + * Konami-JS ~ + * :: Now with support for touch events and multiple instances for + * :: those situations that call for multiple easter eggs! + * Code: https://github.com/snaptortoise/konami-js + * Copyright (c) 2009 George Mandis (georgemandis.com, snaptortoise.com) + * Version: 1.6.2 (7/17/2018) + * Licensed under the MIT License (http://opensource.org/licenses/MIT) + * Tested in: Safari 4+, Google Chrome 4+, Firefox 3+, IE7+, Mobile Safari 2.2.1+ and Android + */ + +var Konami = function(callback) { + var konami = { + addEvent: function(obj, type, fn, ref_obj) { + if (obj.addEventListener) obj.addEventListener(type, fn, false); + else if (obj.attachEvent) { + // IE + obj['e' + type + fn] = fn; + obj[type + fn] = function() { + obj['e' + type + fn](window.event, ref_obj); + }; + obj.attachEvent('on' + type, obj[type + fn]); + } + }, + removeEvent: function(obj, eventName, eventCallback) { + if (obj.removeEventListener) { + obj.removeEventListener(eventName, eventCallback); + } else if (obj.attachEvent) { + obj.detachEvent(eventName); + } + }, + input: '', + pattern: '38384040373937396665', + keydownHandler: function(e, ref_obj) { + if (ref_obj) { + konami = ref_obj; + } // IE + konami.input += e ? e.keyCode : event.keyCode; + + if (konami.input.length > konami.pattern.length) { + konami.input = konami.input.substr(konami.input.length - konami.pattern.length); + } + if (konami.input === konami.pattern) { + konami.code(konami._currentLink); + konami.input = ''; + e.preventDefault(); + return false; + } + }, + load: function(link) { + this._currentLink = link; + this.addEvent(document, 'keydown', this.keydownHandler, this); + this.iphone.load(link); + }, + unload: function() { + this.removeEvent(document, 'keydown', this.keydownHandler); + this.iphone.unload(); + }, + code: function(link) { + window.location = link; + }, + iphone: { + start_x: 0, + start_y: 0, + stop_x: 0, + stop_y: 0, + tap: false, + capture: false, + orig_keys: '', + keys: ['UP', 'UP', 'DOWN', 'DOWN', 'LEFT', 'RIGHT', 'LEFT', 'RIGHT', 'TAP', 'TAP'], + input: [], + code: function(link) { + konami.code(link); + }, + touchmoveHandler: function(e) { + if (e.touches.length === 1 && konami.iphone.capture === true) { + var touch = e.touches[0]; + konami.iphone.stop_x = touch.pageX; + konami.iphone.stop_y = touch.pageY; + konami.iphone.tap = false; + konami.iphone.capture = false; + konami.iphone.check_direction(); + } + }, + touchendHandler: function() { + konami.iphone.input.push(konami.iphone.check_direction()); + + if (konami.iphone.input.length > konami.iphone.keys.length) konami.iphone.input.shift(); + + if (konami.iphone.input.length === konami.iphone.keys.length) { + var match = true; + for (var i = 0; i < konami.iphone.keys.length; i++) { + if (konami.iphone.input[i] !== konami.iphone.keys[i]) { + match = false; + } + } + if (match) { + konami.iphone.code(konami._currentLink); + } + } + }, + touchstartHandler: function(e) { + konami.iphone.start_x = e.changedTouches[0].pageX; + konami.iphone.start_y = e.changedTouches[0].pageY; + konami.iphone.tap = true; + konami.iphone.capture = true; + }, + load: function(link) { + this.orig_keys = this.keys; + konami.addEvent(document, 'touchmove', this.touchmoveHandler); + konami.addEvent(document, 'touchend', this.touchendHandler, false); + konami.addEvent(document, 'touchstart', this.touchstartHandler); + }, + unload: function() { + konami.removeEvent(document, 'touchmove', this.touchmoveHandler); + konami.removeEvent(document, 'touchend', this.touchendHandler); + konami.removeEvent(document, 'touchstart', this.touchstartHandler); + }, + check_direction: function() { + x_magnitude = Math.abs(this.start_x - this.stop_x); + y_magnitude = Math.abs(this.start_y - this.stop_y); + x = this.start_x - this.stop_x < 0 ? 'RIGHT' : 'LEFT'; + y = this.start_y - this.stop_y < 0 ? 'DOWN' : 'UP'; + result = x_magnitude > y_magnitude ? x : y; + result = this.tap === true ? 'TAP' : result; + return result; + }, + }, + }; + + typeof callback === 'string' && konami.load(callback); + if (typeof callback === 'function') { + konami.code = callback; + konami.load(); + } + + return konami; +}; + +if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = Konami; +} else { + if (typeof define === 'function' && define.amd) { + define([], function() { + return Konami; + }); + } else { + window.Konami = Konami; + } +} +/* eslint-enable */