1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-25 08:48:06 +08:00
2024-07-03 14:32:10 +08:00

203 lines
14 KiB
JavaScript

Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.onappend.style(can, wiki.FEEL)
can.run({}, [], function(_msg) { can.db.albums = _msg
can.ui = can.onappend.layout(can), can.user.isMobile && (can.onaction.list = [web.UPLOAD]), cb && cb(msg)
if (can.base.isIn(can.Action("sort")||"", mdb.TIME, "")) {
can.onimport._project(can, msg)
} else {
can.onaction.sort({}, can, "sort", can.Action("sort"))
} can.onimport.page(can, can.db.list, can.db.begin = 0)
can.onmotion.toggle(can, can.ui.display, can.user.isMobile || can.page.isDisplay(can.ui.project)), can.onimport.layout(can)
})
},
_project: function(can, msg) { can.db.list = [], can.db.dir_root = msg.Option(nfs.DIR_ROOT)
can.ui.albums = can.page.Appends(can, can.ui.project, ["albums"])._target
can.db.albums.Table(function(value) {
can.page.Append(can, can.ui.albums, [{view: "item album "+(can.base.beginWith(can.Option(nfs.PATH), value.path)? "select": ""), background: value.cover, list: [
{img: can.misc.Resource(can, value.cover||"usr/icons/background.jpg")}, {text: value.name},
], onclick: function(event) {
can.Option(nfs.PATH, value.path), can.Update()
}, oncontextmenu: function(event) {
can.user.carteItem(event, can, value)
}}])
})
can.page.Append(can, can.ui.albums, [{view: ["item album create", "", "+"], onclick: function(event) {
can.Update(event, [ctx.ACTION, mdb.CREATE])
}}])
can.ui.filter = can.onappend.filter(can, can.ui.project)
msg.Table(function(item) { item.name = can.base.trimPrefix(item.path, can.Option(nfs.PATH))
can.base.endWith(item.path, "/") && (item.nick = [{img: can.misc.Resource(can, "usr/icons/dir.png")}, {text: [item.name, "", mdb.NAME]}])
can.base.endWith(item.path, nfs.PS)? can.onimport.item(can, item, function(event) { can.Option(nfs.PATH, item.path) && can.Update(event) }): can.db.list.push(item)
})
can.onmotion.cacheClear(can, "", can.ui.content)
can.db.hash[0] && msg.path.indexOf(can.db.hash[0]) == -1 && (can.db.hash[0] = "")
can.core.List(can.db.list, function(item, index) { var last = can.onexport.progress(can, "p."+item.path);
(!can.db.hash[0] || can.db.hash[0] == can.Option(nfs.PATH) || can.db.hash[0].indexOf(can.Option(nfs.PATH)) == -1) && (can.db.hash[0] = item.path)
item.nick = [item.cover? {img: can.misc.Resource(can, item.cover)}:
can.misc.isImage(can, item.path)? {img: can.misc.Resource(can, item.path)}:
can.misc.isVideo(can, item.path)? {img: can.misc.Resource(can, "usr/icons/QuickTime Player.png")}:
can.misc.isAudio(can, item.path)? {img: can.misc.Resource(can, "usr/icons/Music.png")}: null,
{text: [item.name, "", mdb.NAME]}, {text: [last||"", "", "progress"]},
can.Option(nfs.PATH) != "usr/icons/" && can.base.isIn(can.Action("sort")||"", mdb.TIME, "")? {text: [can.base.TimeTrim(item.time), "", mdb.TIME]}: {text: [item.size, "", nfs.SIZE]},
]
item.title = [item.time, item.path, item.size].join("\n")
item._hash = item.path, item._title = item.path.split("/").pop()
item._target = can.onimport.item(can, item, function(event, item, show, target) { can.onimport._content(can, item, index, target) })
item.title = ""
})
},
_content: function(can, item, index, target) { can.Option(nfs.FILE, item.name), can.Status(item), can.ui.video = item._video, can.ui.current = item
if (can.onexport.progress(can, "p."+item.path) == "100%") { can.onexport.progress(can, "p."+item.path, ""), can.onexport.progress(can, item.path, "") }
if (can.misc.isImage(can, item.path)) { can.onmotion.delay(can, function() { can.onaction.playnext(can) }, 5000) }
if (!can.onmotion.cache(can, function() { return item.path }, can.ui.content)) { var progress
item._cb = function(event, video) { can.ui.video = item._video = video
var p = parseInt(video.currentTime*100/video.duration); can.page.Select(can, target, "span.progress", function(target) { target.innerText = p+"%" })
if (!progress) { progress = can.page.Append(can, can.ui.content, ["progress"])._target } can.page.style(can, progress, html.WIDTH, can.ui.content.offsetWidth*p/100)
}
var _target = can.onimport.file(can, item.path, item, index, can.ui.content, true); _target.focus()
can.onappend._toggle(can, can.ui.content, function() { can.onaction.prev({}, can) }, function() { can.onaction.next({}, can) })
}
if (index < can.db.begin || index >= can.db.begin+can.db.limit) {
can.onimport.page(can, can.db.list, can.db.begin = index-index%can.db.limit)
} can.onmotion.select(can, can.ui.display, "*", item._display)
},
_file: function(can, path) {
return (location.href.indexOf(ice.HTTP) == 0? location.origin: "http://localhost:9020")+can.misc.Resource(can, can.db.dir_root+path, can.ConfSpace())
},
file: function(can, path, item, index, target, auto) { item._path = path = can.onimport._file(can, path)
var cb = can.onfigure[can.base.Ext(path)]||can.onfigure[wiki.IMAGE]
return cb && can.page.Append(can, target||can.ui.display, [cb(can, item, auto)])._target
},
page: function(can, list, begin) { can.onmotion.clear(can, can.ui.display)
begin = parseInt(begin||can.db.begin||0), can.db.limit = can.base.Min((parseInt(can.ui.display.offsetWidth/110)||5)-1, 3)
for (var i = begin; i < begin+can.db.limit; i++) { if (list && list[i]) { list[i]._display = can.onimport.file(can, list[i].path, list[i], i) } }
can.onappend._toggle(can, can.ui.display, function(event) { can.onaction.prevpage(event, can) }, function(event) { can.onaction.nextpage(event, can) })
can.Status({begin: begin, limit: can.db.limit, total: list.length})
},
}, [""])
Volcanos(chat.ONFIGURE, {
png: function(can, item) { return can.onfigure.image(can, item) },
jpg: function(can, item) { return can.onfigure.image(can, item) },
jpeg: function(can, item) { return can.onfigure.image(can, item) },
image: function(can, item) { return {img: item._path, title: item.title, onclick: function(event) { item._target.click() }} },
video: function(can, item, auto) { var init, last = can.onexport.progress(can, item.path)||0
var meta = {type: html.VIDEO, title: item.title, data: {src: item._path, controls: auto, autoplay: auto},
onclick: function(event) { item._target.click() },
onratechange: function(event) { can.onexport.storage(can, "rate", event.target.playbackRate) },
onvolumechange: function(event) { can.onexport.storage(can, "volume", event.target.volume) },
onloadedmetadata: function(event) { item._cb && item._cb(event, event.target)
event.target.volume = can.onexport.storage(can, "volume")||0.5
event.target.playbackRate = can.onexport.storage(can, "rate")||1
},
ontimeupdate: function(event) { if (event.target.currentTime == 0) { return } item._cb && item._cb(event, event.target)
can.Status("position", can.onexport.position(can, event.target.currentTime-1, event.target.duration))
can.onexport.progress(can, "p."+item.path, parseInt(event.target.currentTime*100/event.target.duration)+"%")
can.onexport.progress(can, item.path, event.target.currentTime)
if (!init) { init = true, event.target.currentTime = last }
},
onended: function(event) { can.onaction.playnext(can) },
}
if (!auto && can.misc.isVideo(can, item.path) && !can.user.isChrome) {
return {view: html.AUDIO, list: [{img: can.misc.Resource(can, item.cover||"usr/icons/QuickTime Player.png", can.ConfSpace()), className: "cover"}, {text: [item.name, "", mdb.NAME]}], onclick: meta.onclick}
}
return meta
},
audio: function(can, item, auto) { var meta = can.onfigure.video(can, item, auto); meta.type = html.AUDIO
return {view: html.AUDIO, list: [{img: can.misc.Resource(can, item.cover||"usr/icons/Music.png", can.ConfSpace()), className: "cover"}, {text: [item.name, "", mdb.NAME]}, meta], onclick: meta.onclick}
},
webm: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mov: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
m4v: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mp4: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mp3: function(can, item, auto) { return can.onfigure.audio(can, item, auto) },
})
Volcanos(chat.ONACTION, {
list: [
"mkdir", "upload", "record1", "record2",
["sort", mdb.TIME, nfs.PATH, nfs.SIZE],
["order", "repeat", "range", "loop", "random"],
],
record0: function(event, can, name, cb) { can.user.input(event, can, [{name: nfs.FILE, value: name}], function(list) {
var height = window.innerHeight, width = window.innerWidth
navigator.mediaDevices.getDisplayMedia({video: {height: height*8, width: width*8}}).then(function(stream) {
can.core.Next([3, 2, 1], function(item, next) { can.user.toast(can, item + "s 后开始截图"), can.onmotion.delay(can, next, 1000) }, function() { can.onmotion.clearFloat(can)
can.onmotion.delay(can, function() {
cb(stream, function(blobs, ext) { var msg = can.request(event); msg._upload = new File(blobs, list[0]+nfs.PT+ext)
can.runAction(msg, html.UPLOAD, [], function(msg) { can.user.toast(can, "上传成功")
can.db.hash = can.onexport.hash(can, encodeURIComponent(msg.Result())), can.Update()
}), can.core.List(stream.getTracks(), function(item) { item.stop() })
})
}, 300)
})
}).catch(function(err) { can.user.toast(can, err.name + ": " + err.message) })
}) },
record1: function(event, can) { can.onaction.record0(event, can, "Screenshot "+can.base.Time(null), function(stream, cb) { var height = window.innerHeight
var video = can.page.Append(can, document.body, [{type: html.VIDEO, height: height}])._target; video.srcObject = stream, video.onloadedmetadata = function() {
video.play(), height = video.offsetHeight, width = video.offsetWidth
var canvas = can.page.Append(can, document.body, [{type: html.CANVAS, height: height, width: width}])._target; canvas.getContext("2d").drawImage(video, 0, 0, width, height)
canvas.toBlob(function(blob) { cb([blob], nfs.PNG) })
}
}) },
record2: function(event, can) { if (can.ui.recorder) { return can.ui.recorder.stop() }
can.onaction.record0(event, can, "Screenshot "+can.base.Time(null), function(stream, cb) {
if (can.user.isChrome) {
var recorder = new MediaRecorder(stream, {mimeType: "video/webm;codecs=vp8"})
recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "webm") }
// var recorder = new MediaRecorder(stream, {mimeType: 'video/mp4; codecs="avc1.4d002a"'})
// recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "mp4") }
} else {
var recorder = new MediaRecorder(stream, {mimeType: "video/mp4"})
recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "mp4") }
}
var blobs = []; recorder.ondataavailable = function(res) { blobs.push(res.data) }
can.ui.recorder = recorder, recorder.start(1)
})
},
fullscreen: function(event, can, button) { var show = can.onmotion.toggle(can, can.ui.project)
can.onmotion.toggle(can, can.ui.display, show), can.onmotion.toggle(can, can._status, show)
can.page.ClassList.set(can, can._fields, button, !show), can.page.ClassList.set(can, can.ui.content, html.FLOAT, !show)
can.sup.onimport.size(can.sup, can.sup.ConfHeight(), can.sup.ConfWidth())
},
sort: function(event, can, button, value) {
switch (value) {
case mdb.TIME: can._msg.Sort(value, "str_r"); break
case nfs.PATH: can._msg.Sort(value, "str"); break
case nfs.SIZE: can._msg.Sort(value, "int_r"); break
} can.onimport._project(can, can._msg)
},
playnext: function(can) {
if (can.Action("order") == "repeat") {
if (can.ui.video) { can.ui.video.currentTime = 0, can.ui.video.play() }
}
if (can.Action("order") == "range") { var next = can.ui.current._target.nextSibling
next && can.onmotion.delay(can, function() { next.click() }, 300)
}
if (can.Action("order") == "loop") { var next = can.ui.current._target.nextSibling
next? can.onmotion.delay(can, function() { next.click() }, 300): can.db.list[0]._target.click()
}
if (can.Action("order") == "random") {
can.db.list[parseInt(Math.random()*can.db.list.length)]._target.click()
}
},
prev: function(event, can) { var target = can.ui.current._target; target.previousSibling? target.previousSibling.click(): can.user.toast(can, "已经是第一页了") },
next: function(event, can) { var target = can.ui.current._target; target.nextSibling? target.nextSibling.click(): can.user.toast(can, "已经是最后一页了") },
prevpage: function(event, can) { if (can.db.begin > 0) { can.db.begin -= can.db.limit, can.onimport.page(can, can.db.list) } else { can.user.toast(can, "已经是第一页了") } },
nextpage: function(event, can) { if (can.db.begin + can.db.limit < can.db.list.length) { can.db.begin += can.db.limit, can.onimport.page(can, can.db.list) } else { can.user.toast(can, "已经是最后一页了") } },
})
Volcanos(chat.ONEXPORT, {list: [cli.BEGIN, mdb.LIMIT, mdb.TOTAL, mdb.NAME, nfs.SIZE, mdb.TIME, "position"],
progress: function(can, path, time) { return can.onexport.storage(can, path.split("?")[0], time) },
position: function(can, index, total) { total = total || can.max; return parseInt((index+1)*100/total)+"%"+" = "+(parseInt(index)+1)+nfs.PS+parseInt(total) },
})
Volcanos(chat.ONKEYMAP, {
_mode: {
plugin: {
Escape: function(event, can) { can.onaction.fullscreen(event, can) },
ArrowLeft: function(event, can) { if (can.ui.video) { can.ui.video.currentTime -= 15 } else { can.onaction.prev(event, can) } },
ArrowRight: function(event, can) { if (can.ui.video) { can.ui.video.currentTime += 15 } else { can.onaction.next(event, can) } },
ArrowDown: function(event, can) { try { can.user.toast(can, "volume: "+parseInt((can.ui.video.volume -= 0.1)*100)) } catch (e) {} },
ArrowUp: function(event, can) { try { can.user.toast(can, "volume: "+parseInt((can.ui.video.volume += 0.1)*100)) } catch (e) {} },
" ": function(event, can) { if (can.ui.video) { can.ui.video.paused? can.ui.video.play(): can.ui.video.pause() } },
},
},
})