Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Draft Queue #457

Merged
merged 28 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
47142c8
PoC
Senryoku May 4, 2023
abb58fe
Random tweaks
Senryoku May 4, 2023
061035d
.
Senryoku May 4, 2023
a64da15
Use uuidv4 for random session ids
Senryoku May 4, 2023
df5ee02
QuickDraft => DraftQueue
Senryoku May 8, 2023
a666311
[WIP] Ready Check
Senryoku May 8, 2023
a93fe03
Removed global 'ManagedSessions'
Senryoku May 8, 2023
8a0ede4
[Client] Draft Queue ready check tweaks
Senryoku May 8, 2023
6b0ebd2
[Client] Don't rely on not reactive property socket.disconnected for …
Senryoku May 8, 2023
1cf60e6
Clean up some unnecessary casts
Senryoku May 8, 2023
dabfff7
Hackish workaround for forcing a pick if timer went to 0 without a re…
Senryoku May 8, 2023
864b158
Allow a managed session to continue drafting when a plyer disconnects…
Senryoku May 8, 2023
c2445c4
Some tweaks; Correctly share the 'managed' session property with the …
Senryoku May 8, 2023
42a43c4
Made Session.managed readonly
Senryoku May 8, 2023
65c1697
Merge branch 'master' into feat/MockDraft
Senryoku May 8, 2023
4463b40
Only accept pre-existing queues.
Senryoku May 8, 2023
523b32a
Use AvailableQueues in client
Senryoku May 9, 2023
d18be90
[Client] Draft Queue style tweaks
Senryoku May 9, 2023
53c2c48
Basic Tests
Senryoku May 9, 2023
1666ba6
Log managed sessions
Senryoku May 9, 2023
b7d5e1a
[Client] Erase sessionID cookie after a managed draft
Senryoku May 9, 2023
3ef75e9
[Client] Add a link back to draft queues after a managed draft
Senryoku May 9, 2023
a167efb
[Client] Description update
Senryoku May 9, 2023
f44a537
DraftQueue: -SIR +DMU
Senryoku May 9, 2023
75a403d
Simple sitemap with the new page
Senryoku May 9, 2023
5f3a176
[Client] News & Patch Note
Senryoku May 9, 2023
ad2cd8e
[Client] Removed canonical URL as I fear it will interfere with /draf…
Senryoku May 9, 2023
c62169b
[Client] Fix main page markup
Senryoku May 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions client/public/sitemap.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
https://draftmancer.com
https://draftmancer.com/draftqueue
https://draftmancer.com/cubeformat.html
60 changes: 43 additions & 17 deletions client/src/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
escapeHTML,
sortableUpdate,
} from "./helper";
import { getCookie, setCookie } from "./cookies";
import { eraseCookie, getCookie, setCookie } from "./cookies";
import { ButtonColor, Alert, fireToast } from "./alerts";
import parseCSV from "./parseCSV";

Expand Down Expand Up @@ -105,7 +105,7 @@ enum PassingOrder {
Repeat,
}

const Sounds: { [name: string]: HTMLAudioElement } = {
export const Sounds: { [name: string]: HTMLAudioElement } = {
start: new Audio("sound/drop_003.ogg"),
next: new Audio("sound/next.mp3"),
countdown: new Audio("sound/click_001.ogg"),
Expand Down Expand Up @@ -184,6 +184,7 @@ export default defineComponent({
News,
PatchNotes: defineAsyncComponent(() => import("./components/PatchNotes.vue")),
PickSummary: defineAsyncComponent(() => import("./components/PickSummary.vue")),
DraftQueue: defineAsyncComponent(() => import("./components/DraftQueue.vue")),
RotisserieDraft: defineAsyncComponent(() => import("./components/RotisserieDraft.vue")),
ScaleSlider,
SetRestrictionComponent: defineAsyncComponent(() => import("./components/SetRestriction.vue")),
Expand All @@ -196,6 +197,10 @@ export default defineComponent({
WinstonDraft: defineAsyncComponent(() => import("./components/WinstonDraft.vue")),
},
data: () => {
const path = window.location.pathname.substring(1).split("/");
const validPages = ["", "draftqueue"];
const page = validPages.includes(path[0]) ? path[0] : "";

let userID: UserID = guid();
let storedUserID = getCookie("userID");
if (storedUserID !== "") {
Expand All @@ -205,22 +210,26 @@ export default defineComponent({
}

let urlParamSession = getUrlVars()["session"];
const sessionID: SessionID = urlParamSession
let sessionID: string | undefined = urlParamSession
? decodeURIComponent(urlParamSession)
: getCookie("sessionID", shortguid());

if (page === "draftqueue") sessionID = undefined;

const userName = initialSettings.userName;

const storedSessionSettings = localStorage.getItem(localStorageSessionSettingsKey) ?? "{}";

const query: any = {
userID: userID,
userName: userName,
sessionSettings: storedSessionSettings,
};
if (sessionID) query.sessionID = sessionID;

// Socket Setup
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io({
query: {
userID: userID,
sessionID: sessionID,
userName: userName,
sessionSettings: storedSessionSettings,
},
query,
});

return {
Expand All @@ -231,6 +240,7 @@ export default defineComponent({

sortableUpdate,

page: page,
// User Data
userID: userID,
userName: userName,
Expand All @@ -241,10 +251,12 @@ export default defineComponent({
vaultProgress: 0,
},
socket: socket,
socketConnected: true,

// Session status
managed: false, // Is the session managed by the server? (i.e. the session doesn't have an owner)
sessionID: sessionID,
sessionOwner: userID as UserID,
sessionOwner: (sessionID ? userID : undefined) as UserID | undefined,
sessionOwnerUsername: userName as string,
sessionUsers: [] as SessionUser[],
disconnectedUsers: {} as { [uid: UserID]: DisconnectedUser },
Expand Down Expand Up @@ -385,6 +397,7 @@ export default defineComponent({
initializeSocket() {
this.socket.on("disconnect", () => {
console.log("Disconnected from server.");
this.socketConnected = false;
// Avoid closing an already opened modal
if (!Swal.isVisible())
Alert.fire({
Expand All @@ -396,6 +409,7 @@ export default defineComponent({

this.socket.io.on("reconnect", (attemptNumber) => {
console.log(`Reconnected to server (attempt ${attemptNumber}).`);
this.socketConnected = true;
// Re-sync collection on reconnect.
if (this.hasCollection) this.socket.emit("setCollection", this.collection);

Expand Down Expand Up @@ -995,7 +1009,8 @@ export default defineComponent({
const startDraftSetup = (name = "draft", msg = "Draft Started!") => {
// Save user ID in case of disconnect
setCookie("userID", this.userID);
setCookie("sessionID", this.sessionID);
if (this.sessionID) setCookie("sessionID", this.sessionID);
this.updateURLQuery();

this.drafting = true;
this.stopReadyCheck();
Expand Down Expand Up @@ -1112,6 +1127,8 @@ export default defineComponent({
this.draftLogLiveComponentRef?.registerPlayerSelectEvents();
});
} else this.draftingState = DraftState.Brewing;
// Clear sessionID for managed sessions
if (this.managed) eraseCookie("sessionID");
});

this.socket.on("pauseDraft", () => {
Expand Down Expand Up @@ -3059,7 +3076,11 @@ export default defineComponent({
this.notificationPermission = "denied";
return;
}
if (this.enableNotifications && Notification.permission !== "granted") {
if (this.enableNotifications) this.requestNotificationPermission();
},
requestNotificationPermission() {
console.log("requestNotificationPermission", Notification.permission);
if (Notification.permission !== "granted") {
Notification.requestPermission().then((permission) => {
this.notificationPermission = permission;
if (permission !== "granted") this.enableNotifications = false;
Expand Down Expand Up @@ -3087,7 +3108,7 @@ export default defineComponent({
copyToClipboard(
`${window.location.protocol}//${window.location.hostname}${
window.location.port ? ":" + window.location.port : ""
}/?session=${encodeURIComponent(this.sessionID)}`
}/?session=${encodeURIComponent(this.sessionID ?? "")}`
);
fireToast("success", "Session link copied to clipboard!");
},
Expand Down Expand Up @@ -3223,7 +3244,7 @@ export default defineComponent({
history.replaceState(
{ sessionID: this.sessionID },
`Draftmancer Session ${this.sessionID}`,
`?session=${encodeURIComponent(this.sessionID)}`
`/?session=${encodeURIComponent(this.sessionID)}`
);
}
},
Expand Down Expand Up @@ -3265,8 +3286,8 @@ export default defineComponent({
return Math.max(0, Math.min(this.burnedCardsPerRound, this.booster.length - this.cardsToPick));
},
waitingForDisconnectedUsers(): boolean {
// Disconnected players do not matter for Team Sealed or Rotisserie Draft.
if (!this.drafting || this.teamSealedState || this.rotisserieDraftState) return false;
// Disconnected players do not matter for managed sessions, Team Sealed or Rotisserie Draft.
if (!this.drafting || this.managed || this.teamSealedState || this.rotisserieDraftState) return false;
return Object.keys(this.disconnectedUsers).length > 0;
},
disconnectedUserNames(): string {
Expand All @@ -3283,6 +3304,7 @@ export default defineComponent({
userName: this.sessionUsers[i].userName,
userID: this.sessionUsers[i].userID,
isBot: false,
isReplaced: false,
isDisconnected: this.sessionUsers[i].userID in this.disconnectedUsers,
});
}
Expand Down Expand Up @@ -3417,6 +3439,9 @@ export default defineComponent({
},
async mounted() {
try {
this.emitter.on("notification", this.pushNotification);
this.emitter.on("requestNotificationPermission", this.requestNotificationPermission);

this.initializeSocket();
this.updateURLQuery();

Expand Down Expand Up @@ -3466,6 +3491,7 @@ export default defineComponent({
}
},
unmounted() {
this.emitter.off("notification", this.pushNotification);
window.removeEventListener("beforeunload", this.beforeunload);
},
watch: {
Expand All @@ -3481,7 +3507,7 @@ export default defineComponent({
}
}
this.socket.io.opts.query!.sessionID = this.sessionID;
this.socket.emit("setSession", this.sessionID, sessionSettings);
if (this.sessionID) this.socket.emit("setSession", this.sessionID, sessionSettings);
}
this.updateURLQuery();
if (this.sessionID) setCookie("sessionID", this.sessionID);
Expand Down
Loading