use animated modal for room browser

This commit is contained in:
Miodec 2026-01-01 22:05:17 +01:00
parent c496172f7d
commit 428c1fafba
5 changed files with 81 additions and 103 deletions

View file

@ -153,13 +153,13 @@
</div>
</div>
<div id="tribeBrowsePublicRoomsPopupWrapper" class="popupWrapper hidden">
<div id="tribeBrowsePublicRoomsPopup">
<dialog id="tribeBrowsePublicRooms" class="modalWrapper hidden">
<div class="modal">
<div class="title">Public rooms</div>
<div class="list"></div>
<div class="error hidden">No public rooms found</div>
</div>
</div>
</dialog>
<div id="tribeRoomCodePopupWrapper" class="popupWrapper hidden">
<div id="tribeRoomCodePopup">

View file

@ -483,8 +483,8 @@ body.darkMode {
}
}
#tribeBrowsePublicRoomsPopupWrapper {
#tribeBrowsePublicRoomsPopup {
#tribeBrowsePublicRooms {
.modal {
color: var(--sub-color);
background: var(--bg-color);
border-radius: var(--roundness);

View file

@ -43,7 +43,7 @@ import { egVideoListener } from "./popups/video-ad-popup";
import "./states/connection";
import "./test/tts";
import "./elements/fps-counter";
import "./popups/tribe-browse-public-rooms-popup";
import "./modals/tribe-browse-public-rooms";
import { isDevEnvironment, addToGlobal } from "./utils/misc";
import * as VersionButton from "./elements/version-button";
import * as Focus from "./test/focus";

View file

@ -0,0 +1,75 @@
import AnimatedModal from "../utils/animated-modal";
import { qs } from "../utils/dom";
import * as Loader from "../elements/loader";
import * as TribeConfig from "../tribe/tribe-config";
import TribeSocket from "../tribe/tribe-socket";
import * as TribeType from "../tribe/types";
import * as Tribe from "../tribe/tribe";
function updateList(list: TribeType.Room[]): void {
// TODO: Confirm type from miodec
const el = $(modal.getModal());
if (list.length === 0) {
el.find(".error").removeClass("hidden");
el.find(".list").addClass("hidden");
return;
}
el.find(".error").addClass("hidden");
el.find(".list").removeClass("hidden");
for (const room of list) {
const html = `
<div class="room" id="${room.id}">
<div class="name">
<div class="title">name</div>
<div class="value">${room.name}</div>
</div>
<div class="players">
<div class="title">players</div>
<div class="value">${room.size}</div>
</div>
<div class="state">
<div class="title">state</div>
<div class="value">${room.state}</div>
</div>
<div class="config">
<div class="title">config</div>
<div class="value">${TribeConfig.getConfigString(room.config)}</div>
</div>
<div class="chevron">
<i class="fas fa-chevron-right"></i>
</div>
</div>
`;
const roomEl = el.find(".list").append(html);
roomEl.on("click", () => {
Tribe.joinRoom(room.id, true);
void modal.hide();
});
}
}
export function show(): void {
Loader.show();
void TribeSocket.out.room.getPublicRooms(0, "").then((r) => {
Loader.hide();
if (r.status !== "Error" && r.rooms) {
updateList(r.rooms);
}
});
void modal.show();
}
const modal = new AnimatedModal({
dialogId: "tribeBrowsePublicRooms",
cleanup: async () => {
const el = $(modal.getModal());
el.find(".search").val("");
el.find(".list").empty();
},
});
qs(".pageTribe .menu .customRooms #browseCustomRooms")?.on("click", (e) => {
show();
});

View file

@ -1,97 +0,0 @@
import * as Tribe from "../tribe/tribe";
import * as TribeConfig from "../tribe/tribe-config";
import * as Loader from "../elements/loader";
import TribeSocket from "../tribe/tribe-socket";
import * as TribeType from "../tribe/types";
function updateList(list: TribeType.Room[]): void {
// TODO: Confirm type from miodec
if (list.length === 0) {
$("#tribeBrowsePublicRoomsPopup .error").removeClass("hidden");
$("#tribeBrowsePublicRoomsPopup .list").addClass("hidden");
return;
}
$("#tribeBrowsePublicRoomsPopup .error").addClass("hidden");
$("#tribeBrowsePublicRoomsPopup .list").removeClass("hidden");
$("#tribeBrowsePublicRoomsPopup .list").html("");
for (const room of list) {
const html = `
<div class="room" id="${room.id}">
<div class="name">
<div class="title">name</div>
<div class="value">${room.name}</div>
</div>
<div class="players">
<div class="title">players</div>
<div class="value">${room.size}</div>
</div>
<div class="state">
<div class="title">state</div>
<div class="value">${room.state}</div>
</div>
<div class="config">
<div class="title">config</div>
<div class="value">${TribeConfig.getConfigString(room.config)}</div>
</div>
<div class="chevron">
<i class="fas fa-chevron-right"></i>
</div>
</div>
`;
$("#tribeBrowsePublicRoomsPopup .list").append(html);
}
}
export function show(): void {
Loader.show();
void TribeSocket.out.room.getPublicRooms(0, "").then((r) => {
Loader.hide();
if (r.status !== "Error" && r.rooms) {
updateList(r.rooms);
}
});
if ($("#tribeBrowsePublicRoomsPopupWrapper").hasClass("hidden")) {
$("#tribeBrowsePublicRoomsPopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 125, () => {
$("#tribeBrowsePublicRoomsPopup .search").trigger("focus");
$("#tribeBrowsePublicRoomsPopup .search").val("");
});
}
}
function hide(): void {
if (!$("#tribeBrowsePublicRoomsPopupWrapper").hasClass("hidden")) {
$("#tribeBrowsePublicRoomsPopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
100,
() => {
$("#tribeBrowsePublicRoomsPopupWrapper").addClass("hidden");
},
);
}
}
$(document).on("click", "#tribeBrowsePublicRoomsPopup .room", (e) => {
const roomId = $(e.currentTarget).attr("id") as string;
Tribe.joinRoom(roomId, true);
hide();
});
$("#tribeBrowsePublicRoomsPopupWrapper").on("click", (e) => {
if ($(e.target).attr("id") === "tribeBrowsePublicRoomsPopupWrapper") {
hide();
}
});
$(".pageTribe .menu .customRooms #browseCustomRooms").on("click", (e) => {
if ($(e.currentTarget).hasClass("disabled")) return;
show();
});