mirror of
https://github.com/lrsjng/h5ai.git
synced 2025-05-23 03:27:08 -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 `.htaccess` auth issues
|
||||
* adds `rust` type and icon
|
||||
* adds `autoplay` option to audio and video preview
|
||||
* removes *Install* section from `README.md`, caused to much trouble
|
||||
* updates build process to use `node 6.0+`, no need for babel now
|
||||
* 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(wrap('\n\n// @include "pre.js"\n\n'))
|
||||
.then(includeit())
|
||||
.then(ife(() => runtime.args.production, uglify()))
|
||||
.then(ife(() => runtime.args.production, uglify({compressor: {warnings: false}})))
|
||||
.then(wrap(runtime.commentJs))
|
||||
.then(write(mapper, {overwrite: true}));
|
||||
});
|
||||
|
|
|
@ -220,6 +220,7 @@
|
|||
*/
|
||||
"preview-aud": {
|
||||
"enabled": true,
|
||||
"autoplay": true,
|
||||
"types": ["aud"]
|
||||
},
|
||||
|
||||
|
@ -283,6 +284,7 @@
|
|||
*/
|
||||
"preview-vid": {
|
||||
"enabled": true,
|
||||
"autoplay": true,
|
||||
"types": ["vid-avi", "vid-flv", "vid-mkv", "vid-mov", "vid-mp4", "vid-mpg", "vid-webm"]
|
||||
},
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pv-content-txt {
|
||||
.raised;
|
||||
|
||||
box-sizing: border-box;
|
||||
max-width: 960px;
|
||||
text-align: left;
|
||||
background: @col-back-paper;
|
||||
|
@ -17,20 +18,19 @@
|
|||
color: #68A9FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.highlighted {
|
||||
|
||||
code {
|
||||
line-height: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
&.markdown {
|
||||
font-size: 1.1em;
|
||||
padding: 8px 24px;
|
||||
|
||||
code {
|
||||
color: #008200;
|
||||
}
|
||||
pre#pv-content-txt {
|
||||
code {
|
||||
line-height: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
div#pv-content-txt {
|
||||
font-size: 1.1em;
|
||||
padding: 8px 24px;
|
||||
|
||||
code {
|
||||
color: #008200;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
background: @col-grey-900;
|
||||
}
|
||||
|
||||
#pv-content {
|
||||
#pv-container {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,38 +1,27 @@
|
|||
const {each, dom} = require('../../util');
|
||||
const event = require('../../core/event');
|
||||
const {dom} = require('../../util');
|
||||
const format = require('../../core/format');
|
||||
const allsettings = require('../../core/settings');
|
||||
const preview = require('./preview');
|
||||
const previewX = require('./preview-x');
|
||||
|
||||
const settings = Object.assign({
|
||||
enabled: false,
|
||||
autoplay: true,
|
||||
types: []
|
||||
}, allsettings['preview-aud']);
|
||||
const tpl = '<audio id="pv-content-aud"/>';
|
||||
|
||||
let state;
|
||||
|
||||
const onAdjustSize = () => {
|
||||
const updateGui = () => {
|
||||
const el = dom('#pv-content-aud')[0];
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elContent = dom('#pv-content')[0];
|
||||
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.centerContent();
|
||||
preview.setLabels([
|
||||
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 => {
|
||||
const $el = dom(tpl)
|
||||
.on('loadedmetadata', () => resolve($el))
|
||||
// .attr('autoplay', 'autoplay')
|
||||
.attr('controls', 'controls')
|
||||
.attr('src', item.absHref);
|
||||
|
||||
if (settings.autoplay) {
|
||||
$el.attr('autoplay', 'autoplay');
|
||||
}
|
||||
});
|
||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
||||
};
|
||||
|
||||
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 = () => {
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
preview.register(settings.types, onEnter);
|
||||
};
|
||||
|
||||
init();
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
const {each, dom} = require('../../util');
|
||||
const {dom} = require('../../util');
|
||||
const server = require('../../server');
|
||||
const event = require('../../core/event');
|
||||
const allsettings = require('../../core/settings');
|
||||
const preview = require('./preview');
|
||||
const previewX = require('./preview-x');
|
||||
|
||||
const settings = Object.assign({
|
||||
enabled: false,
|
||||
|
@ -14,22 +12,15 @@ const tpl = '<img id="pv-content-img"/>';
|
|||
|
||||
let state;
|
||||
|
||||
const onAdjustSize = () => {
|
||||
const updateGui = () => {
|
||||
const el = dom('#pv-content-img')[0];
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elContent = dom('#pv-content')[0];
|
||||
const contentW = elContent.offsetWidth;
|
||||
const contentH = elContent.offsetHeight;
|
||||
const elW = el.offsetWidth;
|
||||
const elH = el.offsetHeight;
|
||||
preview.centerContent();
|
||||
|
||||
dom(el).css({
|
||||
left: (contentW - elW) * 0.5 + 'px',
|
||||
top: (contentH - elH) * 0.5 + 'px'
|
||||
});
|
||||
const elW = el.offsetWidth;
|
||||
|
||||
const labels = [state.item.label];
|
||||
if (!settings.size) {
|
||||
|
@ -61,26 +52,22 @@ const loadImage = item => {
|
|||
return settings.size ? requestSample(href) : href;
|
||||
})
|
||||
.then(href => new Promise(resolve => {
|
||||
const $img = dom(tpl)
|
||||
.on('load', () => resolve($img))
|
||||
const $el = dom(tpl)
|
||||
.on('load', () => resolve($el))
|
||||
.attr('src', href);
|
||||
}));
|
||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
||||
};
|
||||
|
||||
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 = () => {
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
preview.register(settings.types, onEnter);
|
||||
};
|
||||
|
||||
init();
|
||||
|
|
|
@ -1,33 +1,28 @@
|
|||
const lolight = require('lolight');
|
||||
const marked = require('marked');
|
||||
const {each, keys, dom} = require('../../util');
|
||||
const {keys, dom} = require('../../util');
|
||||
const {win} = require('../../globals');
|
||||
const event = require('../../core/event');
|
||||
const allsettings = require('../../core/settings');
|
||||
const preview = require('./preview');
|
||||
const previewX = require('./preview-x');
|
||||
|
||||
const XHR = win.XMLHttpRequest;
|
||||
const settings = Object.assign({
|
||||
enabled: false,
|
||||
styles: {}
|
||||
}, allsettings['preview-txt']);
|
||||
const tplText = '<pre id="pv-content-txt" class="highlighted"></pre>';
|
||||
const tplMarkdown = '<div id="pv-content-txt" class="markdown"></div>';
|
||||
const tplPre = '<pre id="pv-content-txt"></pre>';
|
||||
const tplDiv = '<div id="pv-content-txt"></div>';
|
||||
|
||||
let state;
|
||||
|
||||
const onAdjustSize = () => {
|
||||
const updateGui = () => {
|
||||
const el = dom('#pv-content-txt')[0];
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elContent = dom('#pv-content')[0];
|
||||
|
||||
dom(el).css({
|
||||
height: elContent.offsetHeight - 16 + 'px'
|
||||
});
|
||||
const container = dom('#pv-container')[0];
|
||||
el.style.height = container.offsetHeight - 16 + 'px';
|
||||
|
||||
preview.setLabels([
|
||||
state.item.label,
|
||||
|
@ -56,43 +51,36 @@ const requestTextContent = href => {
|
|||
|
||||
const loadText = item => {
|
||||
return requestTextContent(item.absHref)
|
||||
.catch(err => '[ajax error] ' + err)
|
||||
.catch(err => '[request failed] ' + err)
|
||||
.then(content => {
|
||||
const style = settings.styles[state.item.type];
|
||||
let $text;
|
||||
const style = settings.styles[item.type];
|
||||
|
||||
if (style === 1) {
|
||||
$text = dom(tplText).text(content);
|
||||
return dom(tplPre).text(content);
|
||||
} else if (style === 2) {
|
||||
$text = dom(tplMarkdown).html(marked(content));
|
||||
return dom(tplDiv).html(marked(content));
|
||||
} else if (style === 3) {
|
||||
$text = dom(tplText);
|
||||
const $code = dom('<code/>').text(content).appTo($text);
|
||||
const $code = dom('<code></code>').text(content);
|
||||
win.setTimeout(() => {
|
||||
lolight.el($code[0]);
|
||||
}, content.length < 20000 ? 0 : 500);
|
||||
} else {
|
||||
$text = dom(tplMarkdown).text(content);
|
||||
return dom(tplPre).app($code);
|
||||
}
|
||||
|
||||
return $text;
|
||||
return dom(tplDiv).text(content);
|
||||
});
|
||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
||||
};
|
||||
|
||||
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 = () => {
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
preview.register(keys(settings.styles), onEnter);
|
||||
};
|
||||
|
||||
init();
|
||||
|
|
|
@ -1,34 +1,25 @@
|
|||
const {each, dom} = require('../../util');
|
||||
const event = require('../../core/event');
|
||||
const {dom} = require('../../util');
|
||||
const allsettings = require('../../core/settings');
|
||||
const preview = require('./preview');
|
||||
const previewX = require('./preview-x');
|
||||
|
||||
const settings = Object.assign({
|
||||
enabled: false,
|
||||
autoplay: true,
|
||||
types: []
|
||||
}, allsettings['preview-vid']);
|
||||
const tpl = '<video id="pv-content-vid"/>';
|
||||
|
||||
let state;
|
||||
|
||||
const onAdjustSize = () => {
|
||||
const updateGui = () => {
|
||||
const el = dom('#pv-content-vid')[0];
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elContent = dom('#pv-content')[0];
|
||||
const contentW = elContent.offsetWidth;
|
||||
const contentH = elContent.offsetHeight;
|
||||
preview.centerContent();
|
||||
|
||||
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 elVH = el.videoHeight;
|
||||
|
||||
|
@ -43,26 +34,25 @@ const loadVideo = item => {
|
|||
return new Promise(resolve => {
|
||||
const $el = dom(tpl)
|
||||
.on('loadedmetadata', () => resolve($el))
|
||||
// .attr('autoplay', 'autoplay')
|
||||
.attr('controls', 'controls')
|
||||
.attr('src', item.absHref);
|
||||
|
||||
if (settings.autoplay) {
|
||||
$el.attr('autoplay', 'autoplay');
|
||||
}
|
||||
});
|
||||
// .then(x => new Promise(resolve => setTimeout(() => resolve(x), 1000)));
|
||||
};
|
||||
|
||||
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 = () => {
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
preview.register(settings.types, onEnter);
|
||||
};
|
||||
|
||||
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 event = require('../../core/event');
|
||||
const resource = require('../../core/resource');
|
||||
const allsettings = require('../../core/settings');
|
||||
const store = require('../../core/store');
|
||||
|
||||
|
||||
const settings = Object.assign({
|
||||
enabled: true
|
||||
}, allsettings.preview);
|
||||
const tplOverlay =
|
||||
`<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-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>
|
||||
|
@ -40,7 +40,7 @@ const adjustSize = () => {
|
|||
const margin = isFullscreen ? 0 : 20;
|
||||
const barHeight = isFullscreen ? 0 : 48;
|
||||
|
||||
dom('#pv-content').css({
|
||||
dom('#pv-container').css({
|
||||
width: winWidth - 2 * margin + 'px',
|
||||
height: winHeight - 2 * margin - barHeight + 'px',
|
||||
left: margin + 'px',
|
||||
|
@ -130,7 +130,7 @@ const onKeydown = ev => {
|
|||
|
||||
const onEnter = () => {
|
||||
setLabels([]);
|
||||
dom('#pv-content').clr();
|
||||
dom('#pv-container').clr();
|
||||
dom('#pv-overlay').show();
|
||||
dom(win).on('keydown', onKeydown);
|
||||
adjustSize();
|
||||
|
@ -138,7 +138,7 @@ const onEnter = () => {
|
|||
|
||||
const onExit = () => {
|
||||
setLabels([]);
|
||||
dom('#pv-content').clr();
|
||||
dom('#pv-container').clr();
|
||||
dom('#pv-overlay').hide();
|
||||
dom(win).off('keydown', onKeydown);
|
||||
};
|
||||
|
@ -192,8 +192,98 @@ const showSpinner = (show, src, delay) => {
|
|||
$spinner.show();
|
||||
};
|
||||
|
||||
const isSpinnerVisible = () => {
|
||||
return spinnerVisible;
|
||||
const centerContent = () => {
|
||||
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 = () => {
|
||||
|
@ -208,7 +298,7 @@ const init = () => {
|
|||
.on('mousemove', userAlive)
|
||||
.on('mousedown', userAlive)
|
||||
.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();
|
||||
}
|
||||
})
|
||||
|
@ -228,17 +318,11 @@ const init = () => {
|
|||
.on('load', adjustSize);
|
||||
};
|
||||
|
||||
|
||||
init();
|
||||
|
||||
module.exports = {
|
||||
enter: onEnter,
|
||||
exit: onExit,
|
||||
setIndex,
|
||||
setRawLink,
|
||||
setLabels,
|
||||
setOnIndexChange,
|
||||
setOnAdjustSize,
|
||||
showSpinner,
|
||||
isSpinnerVisible
|
||||
centerContent,
|
||||
state,
|
||||
register
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue