summaryrefslogtreecommitdiff
path: root/public/assets/js
diff options
context:
space:
mode:
authorjulian laplace <julescarbon@gmail.com>2022-10-27 16:42:57 +0200
committerjulian laplace <julescarbon@gmail.com>2022-10-27 16:42:57 +0200
commit83c938702eb67bd6d154bb98b632e64e5e7e183f (patch)
tree7b2b64a91f68cbcd4d4b2089b3a24b3f40bde88f /public/assets/js
parent53644b55eb3a6a355f25e4a30b62c2c78451cd29 (diff)
add player and image viewer
Diffstat (limited to 'public/assets/js')
-rw-r--r--public/assets/js/index.js2
-rw-r--r--public/assets/js/lib/views/details/audio.js101
-rw-r--r--public/assets/js/lib/views/details/audioPlayer.js123
-rw-r--r--public/assets/js/lib/views/stream/hootstream.js79
4 files changed, 224 insertions, 81 deletions
diff --git a/public/assets/js/index.js b/public/assets/js/index.js
index 1c8deb5..ef2b8f4 100644
--- a/public/assets/js/index.js
+++ b/public/assets/js/index.js
@@ -17,6 +17,8 @@ var app = (function () {
};
app.ready = function () {
+ audio.init();
+ app.player = new AudioPlayer();
app.router.route();
};
diff --git a/public/assets/js/lib/views/details/audio.js b/public/assets/js/lib/views/details/audio.js
index fb72e0b..2329886 100644
--- a/public/assets/js/lib/views/details/audio.js
+++ b/public/assets/js/lib/views/details/audio.js
@@ -1,26 +1,27 @@
-var audio = (function () {
- var audio = {};
+const audio = (function () {
+ const audio = {};
- var el,
- music = [],
- current_index = -1;
- var links, comment, parent;
- var selected = false;
- var playing = false;
- var built = false;
- var initted = false;
+ let music = [];
+ let current_index = -1;
+ let links, parent;
+ let selected = false;
+ let playing = false;
+ let built = false;
+ let initted = false;
+ let ui = null;
audio.init = function () {
if (initted) {
audio.index();
return;
}
- comment = document.querySelector("#comment");
parent = document.querySelector("#audio");
audio.index();
audio.build();
- el.src = music[0];
+ if (music.length) {
+ audio.el.src = music[0];
+ }
initted = true;
};
@@ -32,7 +33,7 @@ var audio = (function () {
if (!link.href.match(/\.(mp3|wav|aiff?|m4a|ogg|opus|flac)$/)) return;
link.dataset.index = music.length;
music.push(link);
- if (playing && link.href === el.src) {
+ if (playing && link.href === audio.el.src) {
current_index = parseInt(link.dataset.index);
}
});
@@ -44,28 +45,55 @@ var audio = (function () {
audio.build = function () {
if (built) return;
built = true;
- el = audio.el = document.createElement("audio");
- el.setAttribute("controls", true);
- // el.addEventListener("loadeddata", () => { if (selected) el.play() })
- el.addEventListener("ended", audio.next);
- parent.appendChild(el);
+ audio.el = document.createElement("audio");
+ audio.el.setAttribute("controls", true);
+ // audio.el.addEventListener("loadeddata", () => { if (selected) audio.el.play() })
+ parent.appendChild(audio.el);
document.body.addEventListener("keydown", audio.keydown);
};
audio.destroy = function () {
- el.pause();
- el = null;
- parent.removeChild(el);
+ audio.el.pause();
+ parent.removeChild(audio.el);
+ audio.el = null;
document.body.removeEventListener("keydown", audio.keydown);
built = false;
};
+ audio.listen = function (uiController) {
+ ui = uiController;
+ };
+
audio.play = function (index) {
playing = true;
current_index = (parseInt(index) + music.length) % music.length;
- el.src = music[current_index].href;
- el.play();
+ audio.el.src = music[current_index].href;
+ audio.el.play();
audio.set_cursor();
+ if (ui) {
+ ui.onPlay(music[current_index]);
+ }
+ };
+
+ audio.pause = function () {
+ audio.el.pause();
+ if (ui) {
+ ui.onPause();
+ }
+ };
+
+ audio.toggle = function () {
+ if (audio.el.paused) {
+ audio.el.play();
+ if (ui) {
+ ui.onPlay(music[current_index]);
+ }
+ } else {
+ audio.el.pause();
+ if (ui) {
+ ui.onPause();
+ }
+ }
};
audio.set_cursor = function () {
@@ -84,16 +112,11 @@ var audio = (function () {
audio.play(current_index + 1);
};
- audio.toggle = function () {
- if (el.paused) el.play();
- else el.pause();
- };
-
- audio.keydown = function (e) {
- function element_is_text_input(el) {
- var tagName = el.tagName.toLowerCase();
+ audio.keydown = function (event) {
+ function element_is_text_input(element) {
+ var tagName = element.tagName.toLowerCase();
return (
- (tagName == "input" && el.type == "text") ||
+ (tagName == "input" && element.type == "text") ||
tagName == "textarea" ||
tagName == "button"
);
@@ -101,24 +124,24 @@ var audio = (function () {
if (element_is_text_input(document.activeElement)) {
return;
}
- if (app.typing || e.ctrlKey || e.altKey || e.metaKey) return;
- switch (e.keyCode) {
+ if (app.typing || event.ctrlKey || event.altKey || event.metaKey) return;
+ switch (event.keyCode) {
case 37: // left
- if (e.shiftKey) {
- el.currentTime -= 10;
+ if (event.shiftKey) {
+ audio.el.currentTime -= 10;
} else {
audio.prev();
}
break;
case 39: // right
- if (e.shiftKey) {
- el.currentTime += 10;
+ if (event.shiftKey) {
+ audio.el.currentTime += 10;
} else {
audio.next();
}
break;
case 32: // spacebar
- e.preventDefault();
+ event.preventDefault();
audio.toggle();
break;
}
diff --git a/public/assets/js/lib/views/details/audioPlayer.js b/public/assets/js/lib/views/details/audioPlayer.js
new file mode 100644
index 0000000..700daa5
--- /dev/null
+++ b/public/assets/js/lib/views/details/audioPlayer.js
@@ -0,0 +1,123 @@
+const AudioPlayer = View.extend({
+ el: "#audioPlayer",
+
+ events: {
+ "click .icon": "toggle",
+ },
+
+ initialize: function () {
+ this.$title = this.$(".title");
+
+ this.icon_el = this.$(".icon").get(0);
+ this.pos_el = this.$(".pos").get(0);
+ this.track_el = this.$(".track").get(0);
+ this.dot_el = this.$(".dot").get(0);
+ this.time_el = this.$(".time").get(0);
+
+ this.mousedown = this.mousedown.bind(this);
+ this.mousemove = this.mousemove.bind(this);
+ this.mouseup = this.mouseup.bind(this);
+
+ if (is_mobile) {
+ this.pos_el.addEventListener("touchstart", (e) =>
+ this.mousedown(e.touches[0])
+ );
+ this.pos_el.addEventListener("touchmove", (e) =>
+ this.mousemove(this.e.touches[0])
+ );
+ window.addEventListener("touchend", this.mouseup.bind);
+ } else {
+ this.pos_el.addEventListener("mousedown", this.mousedown);
+ this.pos_el.addEventListener("mousemove", this.mousemove);
+ window.addEventListener("mouseup", this.mouseup);
+ }
+ this.down = false;
+ this.mousex = 0;
+
+ audio.listen(this);
+ audio.el.addEventListener("timeupdate", this.onTimeUpdate.bind(this));
+ },
+
+ /**
+ * Mouse movements
+ * */
+ mousedown: function (e) {
+ e.preventDefault && e.preventDefault();
+ const track_left = this.pos_el.offsetLeft;
+ this.down = true;
+ this.mousex = (e.pageX - track_left) / this.track_el.offsetWidth;
+ },
+
+ mousemove: function (e, isTouch) {
+ if (!this.down) return;
+ const track_left = this.pos_el.offsetLeft;
+ this.mousex = Math.min(
+ Math.max(0, (e.pageX - track_left) / this.track_el.offsetWidth),
+ 1
+ );
+ this.dot_el.style.transform =
+ "translateX(" + this.mousex * this.track_el.offsetWidth + "px)";
+ },
+
+ mouseup: function (e) {
+ if (!this.down) return;
+ this.down = false;
+ var t = this.mousex * (audio.el.duration || 1);
+ audio.el.currentTime = Math.round(t);
+ this.dot_el.style.transform =
+ "translateX(" + this.mousex * this.track_el.offsetWidth + "px)";
+ },
+
+ toggle: function () {
+ audio.toggle();
+ },
+
+ /**
+ * Receiving play events
+ */
+ onPlay: function (element) {
+ if (!this.active) {
+ this.active = true;
+ this.$el.addClass("active");
+ }
+ // if (index === music.length) return stop();
+ if (!this.icon_el.classList.contains("active")) {
+ this.icon_el.classList.add("active");
+ }
+ this.onTimeUpdate();
+
+ if (element) {
+ const title = element.innerText;
+ this.$title.html(title);
+ }
+ },
+
+ onPause: function () {
+ this.icon_el.classList.remove("active");
+ },
+
+ onStop: function () {
+ this.$el.removeClass("active");
+ this.active = false;
+ },
+
+ onTimeUpdate: function () {
+ if (this.down) {
+ return;
+ }
+ let { currentTime, duration } = audio.el;
+ let t = currentTime / (duration || 1);
+ this.dot_el.style.transform =
+ "translateX(" + this.track_el.offsetWidth * t + "px)";
+ this.time_el.innerHTML = time(currentTime) + " / " + time(duration);
+ },
+});
+
+function time(n) {
+ if (!n) return "0:00";
+ n = Math.floor(n);
+ let s = n % 60;
+ if (s < 10) s = "0" + s;
+ let m = Math.floor(n / 60);
+ return m + ":" + s;
+}
diff --git a/public/assets/js/lib/views/stream/hootstream.js b/public/assets/js/lib/views/stream/hootstream.js
index 6c02cc6..777489d 100644
--- a/public/assets/js/lib/views/stream/hootstream.js
+++ b/public/assets/js/lib/views/stream/hootstream.js
@@ -104,12 +104,14 @@ var HootStream = View.extend({
return true;
}
if (
- filters.images &&
- thread.files &&
- thread.files.some((file) => IMAGE_REGEXP.test(file.filename))
+ filters.files &&
+ thread.files.some((file) => !AUDIO_REGEXP.test(file.filename))
) {
return true;
}
+ if (filters.images && thread.images.length) {
+ return true;
+ }
return false;
})
.map(
@@ -120,18 +122,15 @@ var HootStream = View.extend({
const thread = threadLookup[thread_id];
const threadData = {
...thread,
- files:
- filters.images || filters.music
- ? thread.files.filter((file) => {
- if (AUDIO_REGEXP.test(file.filename)) {
- return filters.music;
- }
- if (IMAGE_REGEXP.test(file.filename)) {
- return filters.images;
- }
- return filters.files;
- })
- : [],
+ images: filters.images ? thread.images : [],
+ files: filters.music
+ ? thread.files.filter((file) => {
+ if (AUDIO_REGEXP.test(file.filename)) {
+ return filters.music;
+ }
+ return filters.files;
+ })
+ : [],
comments: filters.hoots ? thread.comments : [],
query: data.query,
};
@@ -257,38 +256,34 @@ var HootStream = View.extend({
comment_count: `${thread.comment_count || 0} c.`,
comment_opacity: age_opacity * get_size_opacity(thread.comment_count),
}),
- // this.renderImages(
- // isViewingThread || postedToday ? images : images.slice(0, 6)
- // ),
+ this.renderImages(
+ isViewingThread || postedToday ? images : images.slice(0, 6)
+ ),
this.renderFiles(
isViewingThread || postedToday ? files : files.slice(0, 10)
),
...this.renderHoots({
- hoots: comments
- .slice(0, 1)
- .map(
- trimComment({
- isViewingThread,
- lines: 5,
- snippetSize: 512,
- cropSize: 256,
- })
- ),
+ hoots: comments.slice(0, 1).map(
+ trimComment({
+ isViewingThread,
+ lines: 5,
+ snippetSize: 512,
+ cropSize: 256,
+ })
+ ),
className: "first_post",
}),
...this.renderHoots({
hoots:
isViewingThread || postedToday
- ? comments
- .slice(1)
- .map(
- trimComment({
- isViewingThread,
- lines: 1,
- snippetSize: 256,
- cropSize: 128,
- })
- )
+ ? comments.slice(1).map(
+ trimComment({
+ isViewingThread,
+ lines: 1,
+ snippetSize: 256,
+ cropSize: 128,
+ })
+ )
: comments
.slice(1)
.slice(-5)
@@ -305,13 +300,13 @@ var HootStream = View.extend({
];
},
- renderImages: function (files) {
- if (!files.length) {
+ renderImages: function (images) {
+ if (!images.length) {
return null;
}
const $table = $("<div class='imageList'>");
- for (const file of files) {
- const $el = this.renderFile(this.imageTemplate, file);
+ for (const image of images) {
+ const $el = this.renderFile(this.imageTemplate, image);
$table.append($el);
}
return $table;