From b2b71b5d1069483d8a07621fbe7aad85eb0e8fc3 Mon Sep 17 00:00:00 2001 From: Mahdi Dibaiee Date: Wed, 16 Sep 2015 15:43:40 +0430 Subject: [PATCH] Improve dialogs, Add Skip button to Tour --- build/main.js | 127 ++++++++++++++++++++---------- build/polyfill.js | 5 +- build/style.css | 16 +++- releases/hawk-1.0.0.zip | Bin 1246696 -> 1248294 bytes src/js/api/files.js | 3 +- src/js/components/dialog.js | 4 +- src/js/components/file-list.js | 4 +- src/js/components/file.js | 4 +- src/js/components/mixins/entry.js | 6 +- src/js/components/root.js | 1 + src/js/tour.js | 23 ++++-- src/less/styles/tour.less | 25 +++++- src/polyfill.js | 5 +- 13 files changed, 159 insertions(+), 64 deletions(-) diff --git a/build/main.js b/build/main.js index 70b585b..5ad1283 100644 --- a/build/main.js +++ b/build/main.js @@ -30116,7 +30116,8 @@ var copy = _asyncToGenerator(function* (file, newPath) { if ((0, _utils.type)(child) === 'File') { Object.defineProperty(child, 'path', { value: oldPath + '/', - enumerable: true + enumerable: true, + configurable: true }); } @@ -30344,7 +30345,7 @@ var Dialog = (function (_Component) { var active = _props.active; var value = _props.value; - var conditionalInput = input ? _react2['default'].createElement('input', { ref: 'input', value: value }) : ''; + var conditionalInput = input ? _react2['default'].createElement('input', { ref: 'input', defaultValue: value }) : ''; var buttons = this.props.buttons.map(function (button, i) { return _react2['default'].createElement( @@ -30361,7 +30362,7 @@ var Dialog = (function (_Component) { if (i % 2 === 0) { groupButtons.push(_react2['default'].createElement( 'div', - { className: 'foot' }, + { className: 'foot', key: i / 2 }, buttons[i], buttons[i + 1] )); @@ -30565,9 +30566,9 @@ var FileList = (function (_Component) { var els = files.map(function (file, index) { var selected = activeFile.indexOf(file) > -1; if ((0, _utils.type)(file) === 'File') { - return _react2['default'].createElement(_file2['default'], { selectView: selectView, selected: selected, key: index, index: index, name: file.name, size: file.size }); + return _react2['default'].createElement(_file2['default'], { selectView: selectView, selected: selected, key: index, index: index, name: file.name, size: file.size, type: file.type }); } else { - return _react2['default'].createElement(_directory2['default'], { selectView: selectView, selected: selected, key: index, index: index, name: file.name, children: file.children }); + return _react2['default'].createElement(_directory2['default'], { selectView: selectView, selected: selected, key: index, index: index, name: file.name, children: file.children, type: file.type }); } }); @@ -30667,8 +30668,6 @@ var File = (function (_Component) { label = _react2['default'].createElement('label', { htmlFor: checkId }); } - console.log(this.props.type); - var clickHandler = this.props.selectView ? this.select.bind(this) : this.open.bind(this); return _react2['default'].createElement( @@ -30694,6 +30693,8 @@ var File = (function (_Component) { }, { key: 'open', value: function open(e) { + e.preventDefault(); + e.stopPropagation(); var file = _store2['default'].getState().get('files')[this.props.index]; var name = file.type === 'application/pdf' ? 'view' : 'open'; @@ -30892,6 +30893,7 @@ var MENU_TOP_SPACE = 20; exports['default'] = { contextMenu: function contextMenu(e) { e.preventDefault(); + e.stopPropagation(); var file = store.getState().get('files')[this.props.index]; var rect = _react2['default'].findDOMNode(this.refs.container).getBoundingClientRect(); @@ -30914,7 +30916,10 @@ exports['default'] = { store.dispatch((0, _actionsFile.active)([file])); }, - select: function select() { + select: function select(e) { + e.preventDefault(); + e.stopPropagation(); + var current = (store.getState().get('activeFile') || []).slice(0); var file = store.getState().get('files')[this.props.index]; @@ -31326,6 +31331,11 @@ var Root = (function (_Component) { 'div', { className: 'tour-dialog' }, 'Hello! Tap each highlighted button to get an understanding of how they work.' + ), + _react2['default'].createElement( + 'button', + { id: 'skip-tour' }, + 'Skip' ) ); } @@ -32537,45 +32547,77 @@ exports['default'] = function () { var tourRan = localStorage.getItem('tourRan'); var wrapper = document.querySelector('#wrapper'); var tour = document.querySelector('.tour-dialog'); + var skip = document.querySelector('#skip-tour'); var timeout = undefined; var shown = 0; if (!tourRan) { - var _iteratorNormalCompletion; + var _iteratorNormalCompletion2; - var _didIteratorError; + var _didIteratorError2; - var _iteratorError; + var _iteratorError2; - var _iterator, _step; + var _iterator2, _step2; (function () { + var listeners = []; + wrapper.classList.add('tour'); + skip.addEventListener('touchstart', function () { + wrapper.classList.remove('tour'); + localStorage.setItem('tourRan', 'true'); + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = listeners[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _step$value = _step.value; + var item = _step$value.item; + var listener = _step$value.listener; + + item.removeEventListener('touchstart', listener); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator['return']) { + _iterator['return'](); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + }); + var items = [].concat(_toConsumableArray(document.querySelectorAll('.tour-item'))).sort(function (a, b) { return +a.dataset.index - +b.dataset.index; }); - var listeners = []; - - _iteratorNormalCompletion = true; - _didIteratorError = false; - _iteratorError = undefined; + _iteratorNormalCompletion2 = true; + _didIteratorError2 = false; + _iteratorError2 = undefined; try { var _loop = function () { - var item = _step.value; + var item = _step2.value; var firstClass = item.className.slice(0, item.className.indexOf(' ')); - var ev = firstClass === 'drawer' ? 'touchstart' : 'click'; - item.addEventListener(ev, function listener(e) { + item.addEventListener('touchstart', function listener(e) { e.preventDefault(); e.stopPropagation(); clearTimeout(timeout); - listeners.push({ item: item, listener: listener, ev: ev }); + listeners.push({ item: item, listener: listener }); shown++; @@ -32586,30 +32628,29 @@ exports['default'] = function () { wrapper.classList.remove('tour'); localStorage.setItem('tourRan', 'true'); - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; try { - for (var _iterator2 = listeners[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var _step2$value = _step2.value; - var _item = _step2$value.item; - var _listener = _step2$value.listener; - var _ev = _step2$value.ev; + for (var _iterator3 = listeners[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var _step3$value = _step3.value; + var _item = _step3$value.item; + var _listener = _step3$value.listener; - _item.removeEventListener(_ev, _listener); + _item.removeEventListener('touchstart', _listener); } } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; + _didIteratorError3 = true; + _iteratorError3 = err; } finally { try { - if (!_iteratorNormalCompletion2 && _iterator2['return']) { - _iterator2['return'](); + if (!_iteratorNormalCompletion3 && _iterator3['return']) { + _iterator3['return'](); } } finally { - if (_didIteratorError2) { - throw _iteratorError2; + if (_didIteratorError3) { + throw _iteratorError3; } } } @@ -32618,20 +32659,20 @@ exports['default'] = function () { }); }; - for (_iterator = items[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + for (_iterator2 = items[Symbol.iterator](); !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { _loop(); } } catch (err) { - _didIteratorError = true; - _iteratorError = err; + _didIteratorError2 = true; + _iteratorError2 = err; } finally { try { - if (!_iteratorNormalCompletion && _iterator['return']) { - _iterator['return'](); + if (!_iteratorNormalCompletion2 && _iterator2['return']) { + _iterator2['return'](); } } finally { - if (_didIteratorError) { - throw _iteratorError; + if (_didIteratorError2) { + throw _iteratorError2; } } } diff --git a/build/polyfill.js b/build/polyfill.js index 8ed9267..0050051 100644 --- a/build/polyfill.js +++ b/build/polyfill.js @@ -29,7 +29,6 @@ function shimDirectory(directory) { directory.toString = function() { return '[object Directory]' }; directory.getFilesAndDirectories = function getFilesAndDirectories() { var current = (this.path || '') + this.name; - console.log('gettingFilesAndDirectories of', this); var children = []; return new Promise(function(resolve, reject) { @@ -50,7 +49,9 @@ function shimDirectory(directory) { type: this.result.type }); Object.defineProperty(file, 'path', { - value: parts.slice(0, -1).join('/') + '/' + value: parts.slice(0, -1).join('/') + '/', + configurable: true, + enumerable: true }); children.push(file); diff --git a/build/style.css b/build/style.css index 2a60b3e..0a60ef6 100644 --- a/build/style.css +++ b/build/style.css @@ -209,7 +209,21 @@ input:checked + label::after { transform: translate(-50%, -50%); z-index: 5; } -.tour-dialog { +.tour #skip-tour { + font-size: 2rem; + display: block; + padding: 0.5rem 5rem; + margin: 1rem auto; + background: #b8e986; + position: fixed; + left: 50%; + top: 65%; + transform: translate(-50%, -50%); + box-shadow: 0 15px 24px 6px rgba(0, 0, 0, 0.2); + z-index: 1; +} +.tour-dialog, +#skip-tour { display: none; } @keyframes pulse { diff --git a/releases/hawk-1.0.0.zip b/releases/hawk-1.0.0.zip index b44ddcab55754944c400609e4d9a5c8108f47980..7f2cb3b188556d29e2cd5843002567f1cb942960 100644 GIT binary patch delta 2026 zcmZWqYitx%6yDiK>CQf8?#%YR+s<}(yRB?ryYxZJqvfF@jZhn_JhWZtw5%*`+1;Y0 zR{dc?kq{xuAp}Z6!yglEEn%Xm4H#pL5iJOU&_oG>1WN)*4H%7h?(DX-IFoa~bI(2Z z+|gQdCqI8E-po#YsUq(#yp>5&Xb zNl0^$l97x^ERqSyjATKwD&!b9ktO+9X~ws)qrElM))fhE2+LJcEYc;zQ4dLn^%n$I z$rVQmi$V`b#AYl_erttPMqEv3d=>v!UH3J zmOLtzl`)oIOW?{Rw?a8!=QnF%c^{t%Bb)dX7`VqZDh)Y&p9IZ2_zW;E zl(?FmH3JsANJi=`XQnN{-hM+m%%8AifNPkOV9Z7IFzFynzW~bvyY8{JF%*RD*q(ONUc*2kS;S6C**`Njy+_!(s(bHkk*{e1WrG$|ft| zel~HMXL2s3vqd8xC{mLLr5?;Tu1L%Y1vPWiVgp>t zCA=^-Hnlt+nc8k91s1tT=4^M?x$rcrj?k6=aFKQ{Am!!F+*OtrGx2mc!@{_W7*R{j z#m8>apby~Xqn6Xa?jbfD!tEVR_M=zyJW;1@aNC1tbz+2j7S`pFWi;#p4CWCl92w;- z@GX_y8s)sO%T3(S-)}I%&0##wF)v9o_|?nJdq^R?;7KyUsZx_wIqxN_)XL~7CTo){ zwESh9+FoxOU^J$kyUU2OyG&>}sHBbw=d^AgYm9&YFJ;q1P_xI70WY5uY;f_sU{%B) zg%7l9S!H`p-n}?iqq#U&`Ral&WR;|cg#gQrB(-+5#|opN?O5LY5xhaL^(P_4-HA6m z)ZSJll@yhsRH6+%<6DA}worSOREmAz?h2_%8!F}bmE~~yZ=pb2UIzX5g#y@mMJR!$ zzXX$`w3_W@i)h^{YzYO!9c{jug^1h|Qk8wb39KDohxhx%QVM6q5(LmO;zEi`7;yo` zHxf9Sz<(HVK9yH!#VU$XZCw9TtyoF>6A8@I#rw@Vv6{*c>*D%9Con}H@7L?&_IB&z z`d{nC@<$#fU=5;IqS^Xzjdrp)Nu!~}sW0qQQ!@|h4WdKUn$9WB>y(0uhpJ$YLCmP7 qwjO3kqcP6X8oMlLqOop#b2dh!t5+IuF^wh-|0M>E=KCZOd;bB&YGytF delta 1364 zcmZ8hZ)_A*5Wn5~yLavG&Th*I?X`Pe+uge!*HUS%SBf4*AZer5kcc7zm+R7AJbUH# zde{_=erQUNfQ^ZxtszZG>KBMKHLjW#H1U%GQxgcFm`c>77$Nw9@Sz%f@9yfq-TdBf z-n@B}nR##C?0Y>cZ}pVLyRA02g?^Xw6J>suj70``&8`bPP&TJ_-oJ3~1;AeE2ImYmp^UXV_jIZ8VJt0_DPmIG1L%~9x(>KWMi466*ZR`P7WBkL^h`? zQAJIrQ^}WAY^{R;tLL$=4nA{*iIXUS>8pn>1~)DWF6;?_3x^s=9D5c70Z%tT4Zce9 zz@-LgV_MLulCZy75Dc7Fp|YZ-E}uvb>m-yyYAq2m#akMz!(|oZ^3rl7mD6A8z}N^= zi4_`D!kRvvA_W=Lv&FS4n%99sVnuI7=Mg>M;Vy2DYp}seEHJNuju#t2!aEu~g3FB{ zU_}rPVsjXR_%KM4ct!&Uz7!_$pVY|oU4TM0PiYLhPQ*n!Bm(W zocJ+0$BSW7ir#vM7r)r#;my@BJX`3Gp3Sh=QBIp6Q!v%a%NMW-(;3 zEQZXL@1!{%lPgjsZv0ttnM=P)?rPGTc+(+oqAWP&X38H6W7O)OGFU9!nn8ijUX?6HZiKXa W(lFxPb_dmZ$-m8RvAk`O$?Pu@a=TXm diff --git a/src/js/api/files.js b/src/js/api/files.js index 06946c7..694dfb6 100644 --- a/src/js/api/files.js +++ b/src/js/api/files.js @@ -133,7 +133,8 @@ export async function copy(file, newPath) { if (type(child) === 'File') { Object.defineProperty(child, 'path', { value: oldPath + '/', - enumerable: true + enumerable: true, + configurable: true }); } diff --git a/src/js/components/dialog.js b/src/js/components/dialog.js index 1c80ccc..44a8255 100644 --- a/src/js/components/dialog.js +++ b/src/js/components/dialog.js @@ -4,7 +4,7 @@ import { template } from 'utils'; export default class Dialog extends Component { render() { let { input, title, description, active, value } = this.props; - let conditionalInput = input ? : ''; + let conditionalInput = input ? : ''; let buttons = this.props.buttons.map((button, i) => { return ( @@ -20,7 +20,7 @@ export default class Dialog extends Component { for (let i = 0; i < buttons.length; i++) { if (i % 2 === 0) { groupButtons.push( -
+
{buttons[i]} {buttons[i+1]}
diff --git a/src/js/components/file-list.js b/src/js/components/file-list.js index 2cf95b0..a4b6f31 100644 --- a/src/js/components/file-list.js +++ b/src/js/components/file-list.js @@ -21,9 +21,9 @@ export default class FileList extends Component { let els = files.map((file, index) => { let selected = activeFile.indexOf(file) > -1; if (type(file) === 'File') { - return ; + return ; } else { - return + return } }); diff --git a/src/js/components/file.js b/src/js/components/file.js index fa20cef..dc47894 100644 --- a/src/js/components/file.js +++ b/src/js/components/file.js @@ -18,8 +18,6 @@ export default class File extends Component { label = ; } - console.log(this.props.type); - let clickHandler = this.props.selectView ? this.select.bind(this) : this.open.bind(this); @@ -39,6 +37,8 @@ export default class File extends Component { } open(e) { + e.preventDefault(); + e.stopPropagation(); let file = store.getState().get('files')[this.props.index]; let name = file.type === 'application/pdf' ? 'view' : 'open'; diff --git a/src/js/components/mixins/entry.js b/src/js/components/mixins/entry.js index 8cd2c01..4095d2a 100644 --- a/src/js/components/mixins/entry.js +++ b/src/js/components/mixins/entry.js @@ -8,6 +8,7 @@ const MENU_TOP_SPACE = 20; export default { contextMenu(e) { e.preventDefault(); + e.stopPropagation(); let file = store.getState().get('files')[this.props.index]; let rect = React.findDOMNode(this.refs.container).getBoundingClientRect(); @@ -27,7 +28,10 @@ export default { store.dispatch(active([file])); }, - select() { + select(e) { + e.preventDefault(); + e.stopPropagation(); + let current = (store.getState().get('activeFile') || []).slice(0); let file = store.getState().get('files')[this.props.index]; diff --git a/src/js/components/root.js b/src/js/components/root.js index 581c64f..d21b430 100644 --- a/src/js/components/root.js +++ b/src/js/components/root.js @@ -55,6 +55,7 @@ export default class Root extends Component {
Hello! Tap each highlighted button to get an understanding of how they work.
+
); } diff --git a/src/js/tour.js b/src/js/tour.js index 09e4551..32ddd9e 100644 --- a/src/js/tour.js +++ b/src/js/tour.js @@ -15,30 +15,39 @@ export default function() { let tourRan = localStorage.getItem('tourRan'); let wrapper = document.querySelector('#wrapper'); let tour = document.querySelector('.tour-dialog'); + let skip = document.querySelector('#skip-tour'); let timeout; let shown = 0; if (!tourRan) { + let listeners = []; + wrapper.classList.add('tour'); + skip.addEventListener('touchstart', () => { + wrapper.classList.remove('tour'); + localStorage.setItem('tourRan', 'true'); + + for (let {item, listener} of listeners) { + item.removeEventListener('touchstart', listener); + } + }) + let items = [...document.querySelectorAll('.tour-item')].sort((a, b) => { return (+a.dataset.index) - (+b.dataset.index); }); - let listeners = []; - for (let item of items) { let firstClass = item.className.slice(0, item.className.indexOf(' ')); - let ev = firstClass === 'drawer' ? 'touchstart' : 'click'; - item.addEventListener(ev, function listener(e) { + item.addEventListener('touchstart', function listener(e) { e.preventDefault(); e.stopPropagation(); clearTimeout(timeout); - listeners.push({item, listener, ev}); + listeners.push({item, listener}); shown++; @@ -49,8 +58,8 @@ export default function() { wrapper.classList.remove('tour'); localStorage.setItem('tourRan', 'true'); - for (let {item, listener, ev} of listeners) { - item.removeEventListener(ev, listener); + for (let {item, listener} of listeners) { + item.removeEventListener('touchstart', listener); } } }, DIALOG_HIDE_DELAY); diff --git a/src/less/styles/tour.less b/src/less/styles/tour.less index 8882bc1..5cc9f31 100644 --- a/src/less/styles/tour.less +++ b/src/less/styles/tour.less @@ -108,9 +108,32 @@ z-index: 5; } + + #skip-tour { + font-size: 2rem; + + display: block; + + padding: 0.5rem 5rem; + + margin: 1rem auto; + + .btn.success; + + position: fixed; + + left: 50%; + top: 65%; + + transform: translate(-50%, -50%); + + .shadow-16; + + z-index: 1; + } } -.tour-dialog { +.tour-dialog, #skip-tour { display: none; } diff --git a/src/polyfill.js b/src/polyfill.js index 8ed9267..0050051 100644 --- a/src/polyfill.js +++ b/src/polyfill.js @@ -29,7 +29,6 @@ function shimDirectory(directory) { directory.toString = function() { return '[object Directory]' }; directory.getFilesAndDirectories = function getFilesAndDirectories() { var current = (this.path || '') + this.name; - console.log('gettingFilesAndDirectories of', this); var children = []; return new Promise(function(resolve, reject) { @@ -50,7 +49,9 @@ function shimDirectory(directory) { type: this.result.type }); Object.defineProperty(file, 'path', { - value: parts.slice(0, -1).join('/') + '/' + value: parts.slice(0, -1).join('/') + '/', + configurable: true, + enumerable: true }); children.push(file);