mirror of
https://github.com/lrsjng/h5ai.git
synced 2025-05-23 11:37:03 -04:00
Update preview code.
This commit is contained in:
parent
8a4ccd098c
commit
20e080751d
11 changed files with 166 additions and 194 deletions
|
@ -10,6 +10,7 @@
|
||||||
* fixes shell command detection on Windows
|
* fixes shell command detection on Windows
|
||||||
* fixes `.htaccess` auth issues
|
* fixes `.htaccess` auth issues
|
||||||
* adds `rust` type and icon
|
* adds `rust` type and icon
|
||||||
|
* adds `autoplay` option to audio and video preview
|
||||||
* removes *Install* section from `README.md`, caused to much trouble
|
* removes *Install* section from `README.md`, caused to much trouble
|
||||||
* updates build process to use `node 6.0+`, no need for babel now
|
* updates build process to use `node 6.0+`, no need for babel now
|
||||||
* replaces `jquery-qrcode` with `kjua`
|
* replaces `jquery-qrcode` with `kjua`
|
||||||
|
|
2
ghu.js
2
ghu.js
|
@ -68,7 +68,7 @@ ghu.task('build:scripts', runtime => {
|
||||||
.then(webpack(webpackCfg([SRC]), {showStats: false}))
|
.then(webpack(webpackCfg([SRC]), {showStats: false}))
|
||||||
.then(wrap('\n\n// @include "pre.js"\n\n'))
|
.then(wrap('\n\n// @include "pre.js"\n\n'))
|
||||||
.then(includeit())
|
.then(includeit())
|
||||||
.then(ife(() => runtime.args.production, uglify()))
|
.then(ife(() => runtime.args.production, uglify({compressor: {warnings: false}})))
|
||||||
.then(wrap(runtime.commentJs))
|
.then(wrap(runtime.commentJs))
|
||||||
.then(write(mapper, {overwrite: true}));
|
.then(write(mapper, {overwrite: true}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -220,6 +220,7 @@
|
||||||
*/
|
*/
|
||||||
"preview-aud": {
|
"preview-aud": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"autoplay": true,
|
||||||
"types": ["aud"]
|
"types": ["aud"]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -283,6 +284,7 @@
|
||||||
*/
|
*/
|
||||||
"preview-vid": {
|
"preview-vid": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"autoplay": true,
|
||||||
"types": ["vid-avi", "vid-flv", "vid-mkv", "vid-mov", "vid-mp4", "vid-mpg", "vid-webm"]
|
"types": ["vid-avi", "vid-flv", "vid-mkv", "vid-mov", "vid-mp4", "vid-mpg", "vid-webm"]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pv-content-txt {
|
#pv-content-txt {
|
||||||
.raised;
|
.raised;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background: @col-back-paper;
|
background: @col-back-paper;
|
||||||
|
@ -17,15 +18,15 @@
|
||||||
color: #68A9FF;
|
color: #68A9FF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.highlighted {
|
pre#pv-content-txt {
|
||||||
|
|
||||||
code {
|
code {
|
||||||
line-height: 1.2em;
|
line-height: 1.2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.markdown {
|
div#pv-content-txt {
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
padding: 8px 24px;
|
padding: 8px 24px;
|
||||||
|
|
||||||
|
@ -33,4 +34,3 @@
|
||||||
color: #008200;
|
color: #008200;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
background: @col-grey-900;
|
background: @col-grey-900;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pv-content {
|
#pv-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,27 @@
|
||||||
const {each, dom} = require('../../util');
|
const {dom} = require('../../util');
|
||||||
const event = require('../../core/event');
|
|
||||||
const format = require('../../core/format');
|
const format = require('../../core/format');
|
||||||
const allsettings = require('../../core/settings');
|
const allsettings = require('../../core/settings');
|
||||||
const preview = require('./preview');
|
const preview = require('./preview');
|
||||||
const previewX = require('./preview-x');
|
|
||||||
|
|
||||||
const settings = Object.assign({
|
const settings = Object.assign({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
autoplay: true,
|
||||||
types: []
|
types: []
|
||||||
}, allsettings['preview-aud']);
|
}, allsettings['preview-aud']);
|
||||||
const tpl = '<audio id="pv-content-aud"/>';
|
const tpl = '<audio id="pv-content-aud"/>';
|
||||||
|
|
||||||
let state;
|
let state;
|
||||||
|
|
||||||
const onAdjustSize = () => {
|
const updateGui = () => {
|
||||||
const el = dom('#pv-content-aud')[0];
|
const el = dom('#pv-content-aud')[0];
|
||||||
if (!el) {
|
if (!el) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const elContent = dom('#pv-content')[0];
|
preview.centerContent();
|
||||||
const contentW = elContent.offsetWidth;
|
|
||||||
const contentH = elContent.offsetHeight;
|
|
||||||
const elW = el.offsetWidth;
|
|
||||||
const elH = el.offsetHeight;
|
|
||||||
|
|
||||||
dom(el).css({
|
|
||||||
left: (contentW - elW) * 0.5 + 'px',
|
|
||||||
top: (contentH - elH) * 0.5 + 'px'
|
|
||||||
});
|
|
||||||
|
|
||||||
preview.setLabels([
|
preview.setLabels([
|
||||||
state.item.label,
|
state.item.label,
|
||||||
format.formatDate(dom('#pv-content-aud')[0].duration * 1000, 'm:ss')
|
format.formatDate(el.duration * 1000, 'm:ss')
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,26 +29,25 @@ const loadAudio = item => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const $el = dom(tpl)
|
const $el = dom(tpl)
|
||||||
.on('loadedmetadata', () => resolve($el))
|
.on('loadedmetadata', () => resolve($el))
|
||||||
// .attr('autoplay', 'autoplay')
|
|
||||||
.attr('controls', 'controls')
|
.attr('controls', 'controls')
|
||||||
.attr('src', item.absHref);
|
.attr('src', item.absHref);
|
||||||
|
|
||||||
|
if (settings.autoplay) {
|
||||||
|
$el.attr('autoplay', 'autoplay');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEnter = (items, idx) => {
|
const onEnter = (items, idx) => {
|
||||||
state = previewX.pvState(items, idx, loadAudio, onAdjustSize);
|
state = preview.state(items, idx, loadAudio, updateGui);
|
||||||
};
|
};
|
||||||
|
|
||||||
const initItem = previewX.initItemFn(settings.types, onEnter);
|
|
||||||
const onViewChanged = added => each(added, initItem);
|
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
if (!settings.enabled) {
|
if (!settings.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.sub('view.changed', onViewChanged);
|
preview.register(settings.types, onEnter);
|
||||||
};
|
};
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
const {each, dom} = require('../../util');
|
const {dom} = require('../../util');
|
||||||
const server = require('../../server');
|
const server = require('../../server');
|
||||||
const event = require('../../core/event');
|
|
||||||
const allsettings = require('../../core/settings');
|
const allsettings = require('../../core/settings');
|
||||||
const preview = require('./preview');
|
const preview = require('./preview');
|
||||||
const previewX = require('./preview-x');
|
|
||||||
|
|
||||||
const settings = Object.assign({
|
const settings = Object.assign({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
@ -14,22 +12,15 @@ const tpl = '<img id="pv-content-img"/>';
|
||||||
|
|
||||||
let state;
|
let state;
|
||||||
|
|
||||||
const onAdjustSize = () => {
|
const updateGui = () => {
|
||||||
const el = dom('#pv-content-img')[0];
|
const el = dom('#pv-content-img')[0];
|
||||||
if (!el) {
|
if (!el) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const elContent = dom('#pv-content')[0];
|
preview.centerContent();
|
||||||
const contentW = elContent.offsetWidth;
|
|
||||||
const contentH = elContent.offsetHeight;
|
|
||||||
const elW = el.offsetWidth;
|
|
||||||
const elH = el.offsetHeight;
|
|
||||||
|
|
||||||
dom(el).css({
|
const elW = el.offsetWidth;
|
||||||
left: (contentW - elW) * 0.5 + 'px',
|
|
||||||
top: (contentH - elH) * 0.5 + 'px'
|
|
||||||
});
|
|
||||||
|
|
||||||
const labels = [state.item.label];
|
const labels = [state.item.label];
|
||||||
if (!settings.size) {
|
if (!settings.size) {
|
||||||
|
@ -61,26 +52,22 @@ const loadImage = item => {
|
||||||
return settings.size ? requestSample(href) : href;
|
return settings.size ? requestSample(href) : href;
|
||||||
})
|
})
|
||||||
.then(href => new Promise(resolve => {
|
.then(href => new Promise(resolve => {
|
||||||
const $img = dom(tpl)
|
const $el = dom(tpl)
|
||||||
.on('load', () => resolve($img))
|
.on('load', () => resolve($el))
|
||||||
.attr('src', href);
|
.attr('src', href);
|
||||||
}));
|
}));
|
||||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEnter = (items, idx) => {
|
const onEnter = (items, idx) => {
|
||||||
state = previewX.pvState(items, idx, loadImage, onAdjustSize);
|
state = preview.state(items, idx, loadImage, updateGui);
|
||||||
};
|
};
|
||||||
|
|
||||||
const initItem = previewX.initItemFn(settings.types, onEnter);
|
|
||||||
const onViewChanged = added => each(added, initItem);
|
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
if (!settings.enabled) {
|
if (!settings.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.sub('view.changed', onViewChanged);
|
preview.register(settings.types, onEnter);
|
||||||
};
|
};
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
|
@ -1,33 +1,28 @@
|
||||||
const lolight = require('lolight');
|
const lolight = require('lolight');
|
||||||
const marked = require('marked');
|
const marked = require('marked');
|
||||||
const {each, keys, dom} = require('../../util');
|
const {keys, dom} = require('../../util');
|
||||||
const {win} = require('../../globals');
|
const {win} = require('../../globals');
|
||||||
const event = require('../../core/event');
|
|
||||||
const allsettings = require('../../core/settings');
|
const allsettings = require('../../core/settings');
|
||||||
const preview = require('./preview');
|
const preview = require('./preview');
|
||||||
const previewX = require('./preview-x');
|
|
||||||
|
|
||||||
const XHR = win.XMLHttpRequest;
|
const XHR = win.XMLHttpRequest;
|
||||||
const settings = Object.assign({
|
const settings = Object.assign({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
styles: {}
|
styles: {}
|
||||||
}, allsettings['preview-txt']);
|
}, allsettings['preview-txt']);
|
||||||
const tplText = '<pre id="pv-content-txt" class="highlighted"></pre>';
|
const tplPre = '<pre id="pv-content-txt"></pre>';
|
||||||
const tplMarkdown = '<div id="pv-content-txt" class="markdown"></div>';
|
const tplDiv = '<div id="pv-content-txt"></div>';
|
||||||
|
|
||||||
let state;
|
let state;
|
||||||
|
|
||||||
const onAdjustSize = () => {
|
const updateGui = () => {
|
||||||
const el = dom('#pv-content-txt')[0];
|
const el = dom('#pv-content-txt')[0];
|
||||||
if (!el) {
|
if (!el) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const elContent = dom('#pv-content')[0];
|
const container = dom('#pv-container')[0];
|
||||||
|
el.style.height = container.offsetHeight - 16 + 'px';
|
||||||
dom(el).css({
|
|
||||||
height: elContent.offsetHeight - 16 + 'px'
|
|
||||||
});
|
|
||||||
|
|
||||||
preview.setLabels([
|
preview.setLabels([
|
||||||
state.item.label,
|
state.item.label,
|
||||||
|
@ -56,43 +51,36 @@ const requestTextContent = href => {
|
||||||
|
|
||||||
const loadText = item => {
|
const loadText = item => {
|
||||||
return requestTextContent(item.absHref)
|
return requestTextContent(item.absHref)
|
||||||
.catch(err => '[ajax error] ' + err)
|
.catch(err => '[request failed] ' + err)
|
||||||
.then(content => {
|
.then(content => {
|
||||||
const style = settings.styles[state.item.type];
|
const style = settings.styles[item.type];
|
||||||
let $text;
|
|
||||||
|
|
||||||
if (style === 1) {
|
if (style === 1) {
|
||||||
$text = dom(tplText).text(content);
|
return dom(tplPre).text(content);
|
||||||
} else if (style === 2) {
|
} else if (style === 2) {
|
||||||
$text = dom(tplMarkdown).html(marked(content));
|
return dom(tplDiv).html(marked(content));
|
||||||
} else if (style === 3) {
|
} else if (style === 3) {
|
||||||
$text = dom(tplText);
|
const $code = dom('<code></code>').text(content);
|
||||||
const $code = dom('<code/>').text(content).appTo($text);
|
|
||||||
win.setTimeout(() => {
|
win.setTimeout(() => {
|
||||||
lolight.el($code[0]);
|
lolight.el($code[0]);
|
||||||
}, content.length < 20000 ? 0 : 500);
|
}, content.length < 20000 ? 0 : 500);
|
||||||
} else {
|
return dom(tplPre).app($code);
|
||||||
$text = dom(tplMarkdown).text(content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $text;
|
return dom(tplDiv).text(content);
|
||||||
});
|
});
|
||||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEnter = (items, idx) => {
|
const onEnter = (items, idx) => {
|
||||||
state = previewX.pvState(items, idx, loadText, onAdjustSize);
|
state = preview.state(items, idx, loadText, updateGui);
|
||||||
};
|
};
|
||||||
|
|
||||||
const initItem = previewX.initItemFn(keys(settings.styles), onEnter);
|
|
||||||
const onViewChanged = added => each(added, initItem);
|
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
if (!settings.enabled) {
|
if (!settings.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.sub('view.changed', onViewChanged);
|
preview.register(keys(settings.styles), onEnter);
|
||||||
};
|
};
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
|
@ -1,34 +1,25 @@
|
||||||
const {each, dom} = require('../../util');
|
const {dom} = require('../../util');
|
||||||
const event = require('../../core/event');
|
|
||||||
const allsettings = require('../../core/settings');
|
const allsettings = require('../../core/settings');
|
||||||
const preview = require('./preview');
|
const preview = require('./preview');
|
||||||
const previewX = require('./preview-x');
|
|
||||||
|
|
||||||
const settings = Object.assign({
|
const settings = Object.assign({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
autoplay: true,
|
||||||
types: []
|
types: []
|
||||||
}, allsettings['preview-vid']);
|
}, allsettings['preview-vid']);
|
||||||
const tpl = '<video id="pv-content-vid"/>';
|
const tpl = '<video id="pv-content-vid"/>';
|
||||||
|
|
||||||
let state;
|
let state;
|
||||||
|
|
||||||
const onAdjustSize = () => {
|
const updateGui = () => {
|
||||||
const el = dom('#pv-content-vid')[0];
|
const el = dom('#pv-content-vid')[0];
|
||||||
if (!el) {
|
if (!el) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const elContent = dom('#pv-content')[0];
|
preview.centerContent();
|
||||||
const contentW = elContent.offsetWidth;
|
|
||||||
const contentH = elContent.offsetHeight;
|
|
||||||
const elW = el.offsetWidth;
|
const elW = el.offsetWidth;
|
||||||
const elH = el.offsetHeight;
|
|
||||||
|
|
||||||
dom(el).css({
|
|
||||||
left: (contentW - elW) * 0.5 + 'px',
|
|
||||||
top: (contentH - elH) * 0.5 + 'px'
|
|
||||||
});
|
|
||||||
|
|
||||||
const elVW = el.videoWidth;
|
const elVW = el.videoWidth;
|
||||||
const elVH = el.videoHeight;
|
const elVH = el.videoHeight;
|
||||||
|
|
||||||
|
@ -43,26 +34,25 @@ const loadVideo = item => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const $el = dom(tpl)
|
const $el = dom(tpl)
|
||||||
.on('loadedmetadata', () => resolve($el))
|
.on('loadedmetadata', () => resolve($el))
|
||||||
// .attr('autoplay', 'autoplay')
|
|
||||||
.attr('controls', 'controls')
|
.attr('controls', 'controls')
|
||||||
.attr('src', item.absHref);
|
.attr('src', item.absHref);
|
||||||
|
|
||||||
|
if (settings.autoplay) {
|
||||||
|
$el.attr('autoplay', 'autoplay');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onEnter = (items, idx) => {
|
const onEnter = (items, idx) => {
|
||||||
state = previewX.pvState(items, idx, loadVideo, onAdjustSize);
|
state = preview.state(items, idx, loadVideo, updateGui);
|
||||||
};
|
};
|
||||||
|
|
||||||
const initItem = previewX.initItemFn(settings.types, onEnter);
|
|
||||||
const onViewChanged = added => each(added, initItem);
|
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
if (!settings.enabled) {
|
if (!settings.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.sub('view.changed', onViewChanged);
|
preview.register(settings.types, onEnter);
|
||||||
};
|
};
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
const {includes, compact, dom} = require('../../util');
|
|
||||||
const preview = require('./preview');
|
|
||||||
|
|
||||||
const initItemFn = (types, onEnter) => {
|
|
||||||
return item => {
|
|
||||||
if (item.$view && includes(types, item.type)) {
|
|
||||||
item.$view.find('a').on('click', ev => {
|
|
||||||
ev.preventDefault();
|
|
||||||
|
|
||||||
const matchedItems = compact(dom('#items .item').map(el => {
|
|
||||||
const matchedItem = el._item;
|
|
||||||
return includes(types, matchedItem.type) ? matchedItem : null;
|
|
||||||
}));
|
|
||||||
|
|
||||||
onEnter(matchedItems, matchedItems.indexOf(item));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const pvState = (items, idx = 0, load, adjust) => {
|
|
||||||
const inst = Object.assign(Object.create(pvState.prototype), {items, load, adjust});
|
|
||||||
preview.setOnAdjustSize(adjust);
|
|
||||||
preview.setOnIndexChange(delta => inst.moveIdx(delta));
|
|
||||||
preview.enter();
|
|
||||||
inst.setIdx(idx);
|
|
||||||
return inst;
|
|
||||||
};
|
|
||||||
|
|
||||||
pvState.prototype = {
|
|
||||||
constructor: pvState,
|
|
||||||
|
|
||||||
setIdx(idx) {
|
|
||||||
this.idx = (idx + this.items.length) % this.items.length;
|
|
||||||
this.item = this.items[this.idx];
|
|
||||||
preview.setLabels([this.item.label]);
|
|
||||||
preview.setIndex(this.idx + 1, this.items.length);
|
|
||||||
preview.setRawLink(this.item.absHref);
|
|
||||||
this.loadContent(this.item);
|
|
||||||
},
|
|
||||||
|
|
||||||
moveIdx(delta) {
|
|
||||||
this.setIdx(this.idx + delta);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadContent(item) {
|
|
||||||
Promise.resolve()
|
|
||||||
.then(() => {
|
|
||||||
dom('#pv-content').hide().clr();
|
|
||||||
preview.showSpinner(true, item.thumbSquare || item.icon, 200);
|
|
||||||
})
|
|
||||||
.then(() => this.load(item))
|
|
||||||
.then($content => {
|
|
||||||
if (item !== this.item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
preview.showSpinner(false);
|
|
||||||
|
|
||||||
dom('#pv-content').clr().app($content).show();
|
|
||||||
this.adjust();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
initItemFn,
|
|
||||||
pvState
|
|
||||||
};
|
|
|
@ -1,16 +1,16 @@
|
||||||
const {each, isFn, isNum, dom} = require('../../util');
|
const {each, isFn, isNum, dom, includes, compact} = require('../../util');
|
||||||
const {win} = require('../../globals');
|
const {win} = require('../../globals');
|
||||||
|
const event = require('../../core/event');
|
||||||
const resource = require('../../core/resource');
|
const resource = require('../../core/resource');
|
||||||
const allsettings = require('../../core/settings');
|
const allsettings = require('../../core/settings');
|
||||||
const store = require('../../core/store');
|
const store = require('../../core/store');
|
||||||
|
|
||||||
|
|
||||||
const settings = Object.assign({
|
const settings = Object.assign({
|
||||||
enabled: true
|
enabled: true
|
||||||
}, allsettings.preview);
|
}, allsettings.preview);
|
||||||
const tplOverlay =
|
const tplOverlay =
|
||||||
`<div id="pv-overlay">
|
`<div id="pv-overlay">
|
||||||
<div id="pv-content"></div>
|
<div id="pv-container"></div>
|
||||||
<div id="pv-spinner"><img class="back"/><img class="spinner" src="${resource.image('spinner')}"/></div>
|
<div id="pv-spinner"><img class="back"/><img class="spinner" src="${resource.image('spinner')}"/></div>
|
||||||
<div id="pv-prev-area" class="hof"><img src="${resource.image('preview-prev')}"/></div>
|
<div id="pv-prev-area" class="hof"><img src="${resource.image('preview-prev')}"/></div>
|
||||||
<div id="pv-next-area" class="hof"><img src="${resource.image('preview-next')}"/></div>
|
<div id="pv-next-area" class="hof"><img src="${resource.image('preview-next')}"/></div>
|
||||||
|
@ -40,7 +40,7 @@ const adjustSize = () => {
|
||||||
const margin = isFullscreen ? 0 : 20;
|
const margin = isFullscreen ? 0 : 20;
|
||||||
const barHeight = isFullscreen ? 0 : 48;
|
const barHeight = isFullscreen ? 0 : 48;
|
||||||
|
|
||||||
dom('#pv-content').css({
|
dom('#pv-container').css({
|
||||||
width: winWidth - 2 * margin + 'px',
|
width: winWidth - 2 * margin + 'px',
|
||||||
height: winHeight - 2 * margin - barHeight + 'px',
|
height: winHeight - 2 * margin - barHeight + 'px',
|
||||||
left: margin + 'px',
|
left: margin + 'px',
|
||||||
|
@ -130,7 +130,7 @@ const onKeydown = ev => {
|
||||||
|
|
||||||
const onEnter = () => {
|
const onEnter = () => {
|
||||||
setLabels([]);
|
setLabels([]);
|
||||||
dom('#pv-content').clr();
|
dom('#pv-container').clr();
|
||||||
dom('#pv-overlay').show();
|
dom('#pv-overlay').show();
|
||||||
dom(win).on('keydown', onKeydown);
|
dom(win).on('keydown', onKeydown);
|
||||||
adjustSize();
|
adjustSize();
|
||||||
|
@ -138,7 +138,7 @@ const onEnter = () => {
|
||||||
|
|
||||||
const onExit = () => {
|
const onExit = () => {
|
||||||
setLabels([]);
|
setLabels([]);
|
||||||
dom('#pv-content').clr();
|
dom('#pv-container').clr();
|
||||||
dom('#pv-overlay').hide();
|
dom('#pv-overlay').hide();
|
||||||
dom(win).off('keydown', onKeydown);
|
dom(win).off('keydown', onKeydown);
|
||||||
};
|
};
|
||||||
|
@ -192,8 +192,98 @@ const showSpinner = (show, src, delay) => {
|
||||||
$spinner.show();
|
$spinner.show();
|
||||||
};
|
};
|
||||||
|
|
||||||
const isSpinnerVisible = () => {
|
const centerContent = () => {
|
||||||
return spinnerVisible;
|
const $container = dom('#pv-container');
|
||||||
|
|
||||||
|
const container = $container[0];
|
||||||
|
const content = $container.children()[0];
|
||||||
|
if (!container || !content) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerW = container.offsetWidth;
|
||||||
|
const containerH = container.offsetHeight;
|
||||||
|
const contentW = content.offsetWidth;
|
||||||
|
const contentH = content.offsetHeight;
|
||||||
|
|
||||||
|
dom(content).css({
|
||||||
|
left: (containerW - contentW) * 0.5 + 'px',
|
||||||
|
top: (containerH - contentH) * 0.5 + 'px'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = (items, idx, load, adjust) => {
|
||||||
|
const inst = Object.assign(Object.create(state.prototype), {items, load, adjust});
|
||||||
|
inst.setIdx(idx);
|
||||||
|
|
||||||
|
setOnAdjustSize(adjust);
|
||||||
|
setOnIndexChange(delta => inst.moveIdx(delta));
|
||||||
|
onEnter();
|
||||||
|
|
||||||
|
return {
|
||||||
|
get item() {
|
||||||
|
return inst.item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
state.prototype = {
|
||||||
|
setIdx(idx) {
|
||||||
|
this.idx = (idx + this.items.length) % this.items.length;
|
||||||
|
this.item = this.items[this.idx];
|
||||||
|
this.updateGui();
|
||||||
|
this.updateContent();
|
||||||
|
},
|
||||||
|
|
||||||
|
moveIdx(delta) {
|
||||||
|
this.setIdx(this.idx + delta);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateGui() {
|
||||||
|
setLabels([this.item.label]);
|
||||||
|
setIndex(this.idx + 1, this.items.length);
|
||||||
|
setRawLink(this.item.absHref);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateContent() {
|
||||||
|
const item = this.item;
|
||||||
|
Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
dom('#pv-container').hide().clr();
|
||||||
|
showSpinner(true, item.thumbSquare || item.icon, 200);
|
||||||
|
})
|
||||||
|
.then(() => this.load(item))
|
||||||
|
// delay for testing
|
||||||
|
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)))
|
||||||
|
.then($content => {
|
||||||
|
if (item !== this.item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showSpinner(false);
|
||||||
|
|
||||||
|
dom('#pv-container').clr().app($content).show();
|
||||||
|
this.adjust();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const register = (types, enter) => {
|
||||||
|
const initItem = item => {
|
||||||
|
if (item.$view && includes(types, item.type)) {
|
||||||
|
item.$view.find('a').on('click', ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
|
||||||
|
const matchedItems = compact(dom('#items .item').map(el => {
|
||||||
|
const matchedItem = el._item;
|
||||||
|
return includes(types, matchedItem.type) ? matchedItem : null;
|
||||||
|
}));
|
||||||
|
|
||||||
|
enter(matchedItems, matchedItems.indexOf(item));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
event.sub('view.changed', added => each(added, initItem));
|
||||||
};
|
};
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
|
@ -208,7 +298,7 @@ const init = () => {
|
||||||
.on('mousemove', userAlive)
|
.on('mousemove', userAlive)
|
||||||
.on('mousedown', userAlive)
|
.on('mousedown', userAlive)
|
||||||
.on('click', ev => {
|
.on('click', ev => {
|
||||||
if (ev.target.id === 'pv-overlay' || ev.target.id === 'pv-content') {
|
if (ev.target.id === 'pv-overlay' || ev.target.id === 'pv-container') {
|
||||||
onExit();
|
onExit();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -228,17 +318,11 @@ const init = () => {
|
||||||
.on('load', adjustSize);
|
.on('load', adjustSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
enter: onEnter,
|
|
||||||
exit: onExit,
|
|
||||||
setIndex,
|
|
||||||
setRawLink,
|
|
||||||
setLabels,
|
setLabels,
|
||||||
setOnIndexChange,
|
centerContent,
|
||||||
setOnAdjustSize,
|
state,
|
||||||
showSpinner,
|
register
|
||||||
isSpinnerVisible
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue