aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/VideoList.hx119
-rw-r--r--src/client/JsApi.hx2
-rw-r--r--src/client/Player.hx107
-rw-r--r--src/client/players/Raw.hx1
-rw-r--r--src/server/Main.hx62
5 files changed, 170 insertions, 121 deletions
diff --git a/src/VideoList.hx b/src/VideoList.hx
index ef1d113..2ed1d8f 100644
--- a/src/VideoList.hx
+++ b/src/VideoList.hx
@@ -2,73 +2,116 @@ package;
import Types.VideoItem;
-// TODO move itemPos to abstract
-// typedef VideoListData = {
-// items:Array<VideoItem>,
-// itemPos:Int
-// }
-@:forward
-abstract VideoList(Array<VideoItem>) from Array<VideoItem> to Array<VideoItem> {
- public function new() {
- this = [];
+using Lambda;
+
+class VideoList {
+ public var length(get, never):Int;
+ public var pos(default, null) = 0;
+ public var isOpen = true;
+
+ final items:Array<VideoItem> = [];
+
+ public function new() {}
+
+ inline function get_length():Int {
+ return items.length;
+ }
+
+ public inline function getCurrentItem():VideoItem {
+ return items[pos];
}
- @:arrayAccess
- public inline function get(i:Int):VideoItem {
- return this[i];
+ public inline function getItem(i:Int):VideoItem {
+ return items[i];
}
- @:arrayAccess
- public inline function set(k:Int, v:VideoItem):VideoItem {
- return this[k] = v;
+ public inline function setItem(i:Int, item:VideoItem):Void {
+ items[i] = item;
+ }
+
+ public inline function getItems():Array<VideoItem> {
+ return items;
+ }
+
+ public function setItems(items:Array<VideoItem>):Void {
+ clear();
+ for (item in items)
+ this.items.push(item);
+ }
+
+ public function setPos(i:Int):Void {
+ if (i < 0 || i > length - 1) i = 0;
+ pos = i;
+ }
+
+ public function exists(f:(item:VideoItem) -> Bool):Bool {
+ return items.exists(f);
}
public function findIndex(f:(item:VideoItem) -> Bool):Int {
var i = 0;
- for (v in this) {
+ for (v in items) {
if (f(v)) return i;
i++;
}
return -1;
}
- public function addItem(item:VideoItem, atEnd:Bool, itemPos:Int):Void {
- if (atEnd) this.push(item);
- else this.insert(itemPos + 1, item);
+ public function addItem(item:VideoItem, atEnd:Bool):Void {
+ if (atEnd) items.push(item);
+ else items.insert(pos + 1, item);
}
- public function setNextItem(pos:Int, itemPos:Int):Int {
- final next = this[pos];
- this.remove(next);
- if (pos < itemPos) itemPos--;
- this.insert(itemPos + 1, next);
- return itemPos;
+ public function setNextItem(nextPos:Int):Void {
+ final next = items[nextPos];
+ items.remove(next);
+ if (nextPos < pos) pos--;
+ items.insert(pos + 1, next);
}
public function toggleItemType(pos:Int):Void {
- this[pos].isTemp = !this[pos].isTemp;
+ items[pos].isTemp = !items[pos].isTemp;
}
- public function removeItem(index:Int, itemPos:Int):Int {
- if (index < itemPos) itemPos--;
- this.remove(this[index]);
- if (itemPos >= this.length) itemPos = 0;
- return itemPos;
+ public function removeItem(index:Int):Void {
+ if (index < pos) pos--;
+ items.remove(items[index]);
+ if (pos >= items.length) pos = 0;
}
- public function skipItem(itemPos:Int):Int {
- final item = this[itemPos];
- if (!item.isTemp) itemPos++;
- else this.remove(item);
- if (itemPos >= this.length) itemPos = 0;
- return itemPos;
+ public function skipItem():Void {
+ final item = items[pos];
+ if (!item.isTemp) pos++;
+ else items.remove(item);
+ if (pos >= items.length) pos = 0;
}
public function itemsByUser(client:Client):Int {
var i = 0;
- for (item in this) {
+ for (item in items) {
if (item.author == client.name) i++;
}
return i;
}
+
+ public inline function clear():Void {
+ items.resize(0);
+ pos = 0;
+ }
+
+ public function shuffle() {
+ final current = items[pos];
+ items.remove(current);
+ shuffleArray(items);
+ items.insert(pos, current);
+ }
+
+ function shuffleArray<T>(arr:Array<T>):Void {
+ for (i => a in arr) {
+ final n = Std.random(arr.length);
+ final b = arr[n];
+ arr[i] = b;
+ arr[n] = a;
+ }
+ }
}
diff --git a/src/client/JsApi.hx b/src/client/JsApi.hx
index d9e6f02..63b98c5 100644
--- a/src/client/JsApi.hx
+++ b/src/client/JsApi.hx
@@ -66,7 +66,7 @@ class JsApi {
}
@:expose
- static function getVideoItems():VideoList {
+ static function getVideoItems():Array<VideoItem> {
final items = player.getItems();
return [
for (item in items) Reflect.copy(item)
diff --git a/src/client/Player.hx b/src/client/Player.hx
index 4d70526..496c355 100644
--- a/src/client/Player.hx
+++ b/src/client/Player.hx
@@ -17,11 +17,10 @@ class Player {
final players:Array<IPlayer>;
final iframePlayer:IPlayer;
final rawPlayer:IPlayer;
- final items = new VideoList();
+ final videoList = new VideoList();
final videoItemsEl = ge("#queue");
final playerEl:Element = ge("#ytapiplayer");
var player:Null<IPlayer>;
- var itemPos = 0;
var isLoaded = false;
var skipSetTime = false;
var skipSetRate = false;
@@ -73,23 +72,23 @@ class Player {
}
public function setNextItem(pos:Int):Void {
- itemPos = items.setNextItem(pos, itemPos);
+ videoList.setNextItem(pos);
final next = videoItemsEl.children[pos];
videoItemsEl.removeChild(next);
- Utils.insertAtIndex(videoItemsEl, next, itemPos + 1);
+ Utils.insertAtIndex(videoItemsEl, next, videoList.pos + 1);
}
public function toggleItemType(pos:Int):Void {
- items.toggleItemType(pos);
+ videoList.toggleItemType(pos);
final el = videoItemsEl.children[pos];
- setItemElementType(el, items[pos].isTemp);
+ setItemElementType(el, videoList.getItem(videoList.pos).isTemp);
}
function setPlayer(newPlayer:IPlayer):Void {
if (player != newPlayer) {
if (player != null) {
- JsApi.fireVideoRemoveEvents(items[itemPos]);
+ JsApi.fireVideoRemoveEvents(videoList.getCurrentItem());
player.removeVideo();
}
main.blinkTabWithTitle("*Video*");
@@ -113,18 +112,15 @@ class Player {
public function setVideo(i:Int):Void {
if (!main.isSyncActive) return;
- final item = items[i];
+ final item = videoList.getItem(i);
var currentPlayer = players.find(p -> p.isSupportedLink(item.url));
if (currentPlayer != null) setPlayer(currentPlayer);
else if (item.isIframe) setPlayer(iframePlayer);
else setPlayer(rawPlayer);
- final childs = videoItemsEl.children;
- if (childs[itemPos] != null) {
- childs[itemPos].classList.remove("queue_active");
- }
- itemPos = i;
- childs[itemPos].classList.add("queue_active");
+ removeActiveLabel(videoList.pos);
+ videoList.setPos(i);
+ addActiveLabel(videoList.pos);
isLoaded = false;
player.loadVideo(item);
@@ -134,7 +130,7 @@ class Player {
public function changeVideoSrc(src:String):Void {
if (player == null) return;
- final item = items[itemPos];
+ final item = videoList.getCurrentItem();
if (item == null) return;
player.loadVideo({
url: src,
@@ -148,7 +144,7 @@ class Player {
}
public function removeVideo():Void {
- JsApi.fireVideoRemoveEvents(items[itemPos]);
+ JsApi.fireVideoRemoveEvents(videoList.getCurrentItem());
player.removeVideo();
ge("#currenttitle").textContent = Lang.get("nothingPlaying");
setPauseIndicator(true);
@@ -175,7 +171,7 @@ class Player {
time: getTime()
}
});
- final hasAutoPause = main.hasLeaderOnPauseRequest() && items.length > 0;
+ final hasAutoPause = main.hasLeaderOnPauseRequest() && videoList.length > 0;
if (hasAutoPause) {
// do not remove leader if user cannot request it back
final group:Client.ClientGroup = main.isAdmin() ? Admin : User;
@@ -184,7 +180,7 @@ class Player {
}
public function onPause():Void {
- final hasAutoPause = main.hasLeaderOnPauseRequest() && items.length > 0
+ final hasAutoPause = main.hasLeaderOnPauseRequest() && videoList.length > 0
&& getTime() > 1;
if (hasAutoPause && !main.hasLeader()) {
JsApi.once(SetLeader, event -> {
@@ -255,10 +251,10 @@ class Player {
</span>
</li>'
);
- items.addItem(item, atEnd, itemPos);
+ videoList.addItem(item, atEnd);
setItemElementType(itemEl, item.isTemp);
if (atEnd) videoItemsEl.appendChild(itemEl);
- else Utils.insertAtIndex(videoItemsEl, itemEl, itemPos + 1);
+ else Utils.insertAtIndex(videoItemsEl, itemEl, videoList.pos + 1);
updateCounters();
}
@@ -273,15 +269,15 @@ class Player {
public function removeItem(url:String):Void {
removeElementItem(url);
- var index = items.findIndex(item -> item.url == url);
+ var index = videoList.findIndex(item -> item.url == url);
if (index == -1) return;
- final isCurrent = items[itemPos].url == url;
- itemPos = items.removeItem(index, itemPos);
+ final isCurrent = videoList.getCurrentItem().url == url;
+ videoList.removeItem(index);
updateCounters();
- if (isCurrent && items.length > 0) {
- setVideo(itemPos);
+ if (isCurrent && videoList.length > 0) {
+ setVideo(videoList.pos);
}
}
@@ -295,47 +291,64 @@ class Player {
}
public function skipItem(url:String):Void {
- var index = items.findIndex(item -> item.url == url);
- if (index == -1) return;
- if (items[index].isTemp) removeElementItem(url);
- index = items.skipItem(index);
+ final pos = videoList.findIndex(item -> item.url == url);
+ if (pos == -1) return;
+ removeActiveLabel(videoList.pos);
+ videoList.setPos(pos);
+ if (videoList.getCurrentItem().isTemp) removeElementItem(url);
+ videoList.skipItem();
updateCounters();
- if (items.length == 0) return;
- setVideo(index);
+ if (videoList.length == 0) return;
+ setVideo(videoList.pos);
+ }
+
+ function addActiveLabel(pos:Int):Void {
+ final childs = videoItemsEl.children;
+ if (childs[videoList.pos] != null) {
+ childs[videoList.pos].classList.add("queue_active");
+ }
+ }
+
+ function removeActiveLabel(pos:Int):Void {
+ final childs = videoItemsEl.children;
+ if (childs[videoList.pos] != null) {
+ childs[videoList.pos].classList.remove("queue_active");
+ }
}
function updateCounters():Void {
- ge("#plcount").textContent = '${items.length} ${Lang.get("videos")}';
+ ge("#plcount").textContent = '${videoList.length} ${Lang.get("videos")}';
ge("#pllength").textContent = totalDuration();
}
- public function getItems():VideoList {
- return items;
+ public function getItems():Array<VideoItem> {
+ return videoList.getItems();
}
public function setItems(list:Array<VideoItem>, ?pos:Int):Void {
- final currentUrl = itemPos >= items.length ? "" : items[itemPos].url;
+ final currentUrl = videoList.pos >= videoList.length ? "" : videoList.getCurrentItem()
+ .url;
clearItems();
- if (pos != null) itemPos = pos;
+ if (pos != null) videoList.setPos(pos);
if (list.length == 0) return;
for (video in list) {
addVideoItem(video, true);
}
- if (currentUrl != items[itemPos].url) setVideo(itemPos);
- else videoItemsEl.children[itemPos].classList.add("queue_active");
+ if (currentUrl != videoList.getCurrentItem().url) setVideo(videoList.pos);
+ else addActiveLabel(videoList.pos);
}
public function clearItems():Void {
- items.resize(0);
+ videoList.clear();
videoItemsEl.textContent = "";
updateCounters();
}
public function refresh():Void {
- if (items.length == 0) return;
+ if (videoList.length == 0) return;
final time = getTime();
removeVideo();
- setVideo(itemPos);
+ setVideo(videoList.pos);
// restore server time for leader with next GetTime
if (main.isLeader()) {
setTime(time);
@@ -357,7 +370,7 @@ class Player {
function totalDuration():String {
var time = 0.0;
- for (item in items) {
+ for (item in videoList.getItems()) {
if (item.isIframe) continue;
time += item.duration;
}
@@ -365,15 +378,15 @@ class Player {
}
public function isListEmpty():Bool {
- return items.length == 0;
+ return videoList.length == 0;
}
public function itemsLength():Int {
- return items.length;
+ return videoList.length;
}
public function getItemPos():Int {
- return itemPos;
+ return videoList.pos;
}
public function hasVideo():Bool {
@@ -381,8 +394,8 @@ class Player {
}
public function getDuration():Float {
- if (itemPos >= items.length) return 0;
- return items[itemPos].duration;
+ if (videoList.pos >= videoList.length) return 0;
+ return videoList.getCurrentItem().duration;
}
public function isVideoLoaded():Bool {
diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx
index 4b78b0f..dc3aed5 100644
--- a/src/client/players/Raw.hx
+++ b/src/client/players/Raw.hx
@@ -127,6 +127,7 @@ class Raw implements IPlayer {
if (Utils.isTouch()) return;
if (controlsHider != null) controlsHider.stop();
controlsHider = Timer.delay(() -> {
+ if (video == null) return;
video.controls = false;
}, 3000);
video.onmousemove = e -> {
diff --git a/src/server/Main.hx b/src/server/Main.hx
index 748c513..3ab0621 100644
--- a/src/server/Main.hx
+++ b/src/server/Main.hx
@@ -54,8 +54,6 @@ class Main {
final videoTimer = new VideoTimer();
final messages:Array<Message> = [];
final logger:Logger;
- var isPlaylistOpen = true;
- var itemPos = 0;
static function main():Void {
new Main({
@@ -245,9 +243,9 @@ class Main {
function getCurrentState():ServerState {
return {
- videoList: videoList,
- isPlaylistOpen: isPlaylistOpen,
- itemPos: itemPos,
+ videoList: videoList.getItems(),
+ isPlaylistOpen: videoList.isOpen,
+ itemPos: videoList.pos,
messages: messages,
timer: {
time: videoTimer.getTime(),
@@ -261,13 +259,10 @@ class Main {
if (!FileSystem.exists(statePath)) return;
trace("Loading state...");
final data:ServerState = Json.parse(File.getContent(statePath));
- videoList.resize(0);
+ videoList.setItems(data.videoList);
messages.resize(0);
- for (item in data.videoList) {
- videoList.push(item);
- }
- isPlaylistOpen = data.isPlaylistOpen;
- itemPos = data.itemPos;
+ videoList.isOpen = data.isPlaylistOpen;
+ videoList.setPos(data.itemPos);
for (message in data.messages) {
messages.push(message);
}
@@ -428,9 +423,9 @@ class Main {
isUnknownClient: true,
clientName: client.name,
clients: clientList(),
- videoList: videoList,
- isPlaylistOpen: isPlaylistOpen,
- itemPos: itemPos,
+ videoList: videoList.getItems(),
+ isPlaylistOpen: videoList.isOpen,
+ itemPos: videoList.pos,
globalIp: globalIp
}
});
@@ -574,7 +569,7 @@ class Main {
case ServerMessage:
case AddVideo:
if (!checkPermission(client, AddVideoPerm)) return;
- if (!isPlaylistOpen) {
+ if (!videoList.isOpen) {
if (!checkPermission(client, LockPlaylistPerm)) return;
}
if (config.totalVideoLimit != 0 && videoList.length >= config.totalVideoLimit) {
@@ -599,7 +594,7 @@ class Main {
serverMessage(client, "videoAlreadyExistsError");
return;
}
- videoList.addItem(item, data.addVideo.atEnd, itemPos);
+ videoList.addItem(item, data.addVideo.atEnd);
broadcast(data);
// Initial timer start if VideoLoaded is not happen
if (videoList.length == 1) restartWaitTimer();
@@ -615,8 +610,8 @@ class Main {
var index = videoList.findIndex(item -> item.url == url);
if (index == -1) return;
- final isCurrent = videoList[itemPos].url == url;
- itemPos = videoList.removeItem(index, itemPos);
+ final isCurrent = videoList.getCurrentItem().url == url;
+ videoList.removeItem(index);
if (isCurrent && videoList.length > 0) {
broadcast(data);
restartWaitTimer();
@@ -656,11 +651,11 @@ class Main {
case GetTime:
if (videoList.length == 0) return;
- final maxTime = videoList[itemPos].duration - 0.01;
+ final maxTime = videoList.getCurrentItem().duration - 0.01;
if (videoTimer.getTime() > maxTime) {
videoTimer.pause();
videoTimer.setTime(maxTime);
- final skipUrl = videoList[itemPos].url;
+ final skipUrl = videoList.getCurrentItem().url;
Timer.delay(() -> {
skipVideo({
type: SkipVideo,
@@ -756,15 +751,16 @@ class Main {
case PlayItem:
if (!checkPermission(client, ChangeOrderPerm)) return;
- itemPos = data.playItem.pos;
+ videoList.setPos(data.playItem.pos);
+ data.playItem.pos = videoList.pos;
restartWaitTimer();
broadcast(data);
case SetNextItem:
if (!checkPermission(client, ChangeOrderPerm)) return;
final pos = data.setNextItem.pos;
- if (pos == itemPos || pos == itemPos + 1) return;
- itemPos = videoList.setNextItem(pos, itemPos);
+ if (pos == videoList.pos || pos == videoList.pos + 1) return;
+ videoList.setNextItem(pos);
broadcast(data);
case ToggleItemType:
@@ -780,21 +776,17 @@ class Main {
case ClearPlaylist:
if (!checkPermission(client, RemoveVideoPerm)) return;
videoTimer.stop();
- videoList.resize(0);
- itemPos = 0;
+ videoList.clear();
broadcast(data);
case ShufflePlaylist:
if (!checkPermission(client, ChangeOrderPerm)) return;
if (videoList.length == 0) return;
- final current = videoList[itemPos];
- videoList.remove(current);
- Utils.shuffle(videoList);
- videoList.insert(itemPos, current);
+ videoList.shuffle();
broadcast({
type: UpdatePlaylist,
updatePlaylist: {
- videoList: videoList
+ videoList: videoList.getItems()
}
});
@@ -802,17 +794,17 @@ class Main {
broadcast({
type: UpdatePlaylist,
updatePlaylist: {
- videoList: videoList
+ videoList: videoList.getItems()
}
});
case TogglePlaylistLock:
if (!checkPermission(client, LockPlaylistPerm)) return;
- isPlaylistOpen = !isPlaylistOpen;
+ videoList.isOpen = !videoList.isOpen;
broadcast({
type: TogglePlaylistLock,
togglePlaylistLock: {
- isOpen: isPlaylistOpen
+ isOpen: videoList.isOpen
}
});
@@ -894,9 +886,9 @@ class Main {
function skipVideo(data:WsEvent):Void {
if (videoList.length == 0) return;
- final item = videoList[itemPos];
+ final item = videoList.getCurrentItem();
if (item.url != data.skipVideo.url) return;
- itemPos = videoList.skipItem(itemPos);
+ videoList.skipItem();
if (videoList.length > 0) restartWaitTimer();
broadcast(data);
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage