ts: use pages modules in admin (kinda), change pseudo-links
pseudo-links are now just links, because i'm lazy and it's easier than fixing an issue. They now take the form `/?invite=code` and `/accounts/?user=userid`. ts/modules.tabs.ts is now a wrapper for ts/modules/pages.ts. Also, fixed no section appearing when visiting the settings tab.
This commit is contained in:
@@ -1804,10 +1804,16 @@ export class accountsList {
|
||||
this.focusAccount(event.detail);
|
||||
});
|
||||
|
||||
isAccountURL = () => { return window.location.pathname.startsWith(window.URLBase + "/accounts/user/"); }
|
||||
// FIXME: Use Query Param! so it doesn't get cleared by pages.ts.
|
||||
isAccountURL = () => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const userID = urlParams.get("user");
|
||||
return Boolean(userID);
|
||||
}
|
||||
|
||||
loadAccountURL = () => {
|
||||
let userID = window.location.pathname.split(window.URLBase + "/accounts/user/")[1].split("?lang")[0];
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const userID = urlParams.get("user");
|
||||
this.focusAccount(userID);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,17 +64,17 @@ export class Activity implements activity, SearchableItem {
|
||||
}
|
||||
|
||||
_genUserLink = (): string => {
|
||||
return `<span role="link" tabindex="0" class="hover:underline cursor-pointer activity-pseudo-link-user" data-id="${this._act.user_id}" data-href="${this._urlBase}accounts/user/${this._act.user_id}">${this._genUserText()}</span>`;
|
||||
return `<a role="link" tabindex="0" class="hover:underline cursor-pointer activity-pseudo-link-user" data-id="${this._act.user_id}" href="${this._urlBase}accounts?user=${this._act.user_id}">${this._genUserText()}</a>`;
|
||||
}
|
||||
|
||||
_genSrcUserLink = (): string => {
|
||||
return `<span role="link" tabindex="0" class="hover:underline cursor-pointer activity-pseudo-link-user" data-id="${this._act.user_id}" data-href="${this._urlBase}accounts/user/${this._act.source}">${this._genSrcUserText()}</span>`;
|
||||
return `<a role="link" tabindex="0" class="hover:underline cursor-pointer activity-pseudo-link-user" data-id="${this._act.user_id}" href="${this._urlBase}accounts?user=${this._act.source}">${this._genSrcUserText()}</a>`;
|
||||
}
|
||||
|
||||
private _renderInvText = (): string => { return `<span class="font-medium font-mono">${this.value || this.invite_code || "???"}</span>`; }
|
||||
|
||||
private _genInvLink = (): string => {
|
||||
return `<span role="link" tabindex="0" class="hover:underline cursor-pointer activity-pseudo-link-invite" data-id="${this.invite_code}" data-href="${this._urlBase}invites/${this.invite_code}">${this._renderInvText()}</span>`;
|
||||
return `<a role="link" tabindex="0" class="hover:underline cursor-pointer activity-pseudo-link-invite" data-id="${this.invite_code}" href="${this._urlBase}?invite=${this.invite_code}">${this._renderInvText()}</a>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -307,17 +307,17 @@ export class Activity implements activity, SearchableItem {
|
||||
const pseudoInvites = this._card.getElementsByClassName("activity-pseudo-link-invite") as HTMLCollectionOf<HTMLAnchorElement>;
|
||||
|
||||
for (let i = 0; i < pseudoUsers.length; i++) {
|
||||
const navigate = (event: Event) => {
|
||||
/*const navigate = (event: Event) => {
|
||||
event.preventDefault()
|
||||
window.tabs.switch("accounts");
|
||||
document.dispatchEvent(accountURLEvent(pseudoUsers[i].getAttribute("data-id")));
|
||||
window.history.pushState(null, document.title, pseudoUsers[i].getAttribute("data-href"));
|
||||
}
|
||||
pseudoUsers[i].onclick = navigate;
|
||||
pseudoUsers[i].onkeydown = navigate;
|
||||
pseudoUsers[i].onkeydown = navigate;*/
|
||||
}
|
||||
for (let i = 0; i < pseudoInvites.length; i++) {
|
||||
const navigate = (event: Event) => {
|
||||
/*const navigate = (event: Event) => {
|
||||
event.preventDefault();
|
||||
window.invites.reload(() => {
|
||||
window.tabs.switch("invites");
|
||||
@@ -326,7 +326,7 @@ export class Activity implements activity, SearchableItem {
|
||||
});
|
||||
}
|
||||
pseudoInvites[i].onclick = navigate;
|
||||
pseudoInvites[i].onkeydown = navigate;
|
||||
pseudoInvites[i].onkeydown = navigate;*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -448,10 +448,15 @@ export class inviteList implements inviteList {
|
||||
this.focusInvite(event.detail);
|
||||
})
|
||||
|
||||
isInviteURL = () => { return window.location.pathname.startsWith(window.URLBase + "/invites/"); }
|
||||
isInviteURL = () => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const inviteCode = urlParams.get("invite");
|
||||
return Boolean(inviteCode);
|
||||
}
|
||||
|
||||
loadInviteURL = () => {
|
||||
let inviteCode = window.location.pathname.split(window.URLBase + "/invites/")[1].split("?lang")[0];
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const inviteCode = urlParams.get("invite");
|
||||
this.focusInvite(inviteCode, window.lang.notif("errorInviteNotFound"));
|
||||
}
|
||||
|
||||
|
||||
+13
-19
@@ -32,24 +32,21 @@ export class PageManager {
|
||||
|
||||
private _onpopstate = (event: PopStateEvent) => {
|
||||
let name = event.state;
|
||||
if (!(event.state in this.pages)) {
|
||||
if (!this.pages.has(event.state)) {
|
||||
name = this.pageList[0]
|
||||
}
|
||||
let success = this.pages[name].show();
|
||||
let success = this.pages.get(name).show();
|
||||
if (!success) {
|
||||
console.log("failed");
|
||||
return;
|
||||
}
|
||||
if (!(this.hideOthers)) {
|
||||
console.log("shoudln't hide others");
|
||||
return;
|
||||
}
|
||||
for (let k of this.pageList) {
|
||||
if (name != k) {
|
||||
this.pages[k].hide();
|
||||
this.pages.get(k).hide();
|
||||
}
|
||||
}
|
||||
console.log("loop ended", this);
|
||||
}
|
||||
|
||||
constructor(c: PageConfig) {
|
||||
@@ -65,42 +62,39 @@ export class PageManager {
|
||||
|
||||
setPage(p: Page) {
|
||||
p.index = this.pageList.length;
|
||||
this.pages[p.name] = p;
|
||||
this.pages.set(p.name, p);
|
||||
this.pageList.push(p.name);
|
||||
}
|
||||
|
||||
load(name: string = "") {
|
||||
if (!(name in this.pages)) return window.history.pushState(name || this.defaultName, this.defaultTitle, "")
|
||||
const p = this.pages[name];
|
||||
if (!this.pages.has(name)) return window.history.pushState(name || this.defaultName, this.defaultTitle, "")
|
||||
const p = this.pages.get(name);
|
||||
this.loadPage(p);
|
||||
}
|
||||
|
||||
loadPage (p: Page) {
|
||||
window.history.pushState(p.name || this.defaultName, p.title, p.url);
|
||||
window.history.pushState(p.name || this.defaultName, p.title, p.url + window.location.search);
|
||||
}
|
||||
|
||||
prev(name: string = "") {
|
||||
if (!(name in this.pages)) return console.error(`previous page ${name} not found`);
|
||||
let p = this.pages[name];
|
||||
if (!this.pages.has(name)) return console.error(`previous page ${name} not found`);
|
||||
let p = this.pages.get(name);
|
||||
let shouldSkip = true;
|
||||
while (shouldSkip && p.index > 0) {
|
||||
p = this.pages[this.pageList[p.index-1]];
|
||||
p = this.pages.get(this.pageList[p.index-1]);
|
||||
shouldSkip = p.shouldSkip();
|
||||
}
|
||||
this.loadPage(p);
|
||||
}
|
||||
|
||||
next(name: string = "") {
|
||||
if (!(name in this.pages)) return console.error(`previous page ${name} not found`);
|
||||
let p = this.pages[name];
|
||||
console.log("next", name, p);
|
||||
console.log("pages", this.pages, this.pageList);
|
||||
if (!this.pages.has(name)) return console.error(`previous page ${name} not found`);
|
||||
let p = this.pages.get(name);
|
||||
let shouldSkip = true;
|
||||
while (shouldSkip && p.index < this.pageList.length) {
|
||||
p = this.pages[this.pageList[p.index+1]];
|
||||
p = this.pages.get(this.pageList[p.index+1]);
|
||||
shouldSkip = p.shouldSkip();
|
||||
}
|
||||
console.log("next ended with", p);
|
||||
this.loadPage(p);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -636,6 +636,7 @@ export class settingsList {
|
||||
}
|
||||
|
||||
private _showPanel = (name: string) => {
|
||||
console.log("showing", name);
|
||||
for (let n in this._sections) {
|
||||
if (n == name) {
|
||||
this._sections[name].visible = true;
|
||||
@@ -919,7 +920,11 @@ export class settingsList {
|
||||
for (let i = 0; i < this._loader.children.length; i++) {
|
||||
this._loader.children[i].classList.remove("invisible");
|
||||
}
|
||||
this._showPanel(this._settings.sections[0].section);
|
||||
for (let s of this._settings.sections) {
|
||||
if (s.meta.disabled) continue;
|
||||
this._showPanel(s.section);
|
||||
break;
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent("settings-loaded"));
|
||||
document.dispatchEvent(new CustomEvent("settings-advancedState", { detail: false }));
|
||||
this._saveButton.classList.add("unfocused");
|
||||
|
||||
+62
-29
@@ -1,44 +1,77 @@
|
||||
import { PageManager, Page } from "../modules/pages.js";
|
||||
|
||||
export interface Tab {
|
||||
page: Page;
|
||||
tabEl: HTMLDivElement;
|
||||
buttonEl: HTMLSpanElement;
|
||||
preFunc?: () => void;
|
||||
postFunc?: () => void;
|
||||
}
|
||||
|
||||
|
||||
export class Tabs implements Tabs {
|
||||
private _current: string = "";
|
||||
tabs: Array<Tab>;
|
||||
private _baseOffset = -1;
|
||||
tabs: Map<string, Tab>;
|
||||
pages: PageManager;
|
||||
|
||||
constructor() {
|
||||
this.tabs = [];
|
||||
this.tabs = new Map<string, Tab>;
|
||||
this.pages = new PageManager({
|
||||
hideOthersOnPageShow: true,
|
||||
defaultName: "invites",
|
||||
defaultTitle: document.title,
|
||||
});
|
||||
}
|
||||
|
||||
addTab = (tabID: string, preFunc = () => void {}, postFunc = () => void {}) => {
|
||||
let tab = {} as Tab;
|
||||
tab.tabID = tabID;
|
||||
tab.tabEl = document.getElementById("tab-" + tabID) as HTMLDivElement;
|
||||
tab.buttonEl = document.getElementById("button-tab-" + tabID) as HTMLSpanElement;
|
||||
addTab = (tabID: string, url: string, preFunc = () => void {}, postFunc = () => void {},) => {
|
||||
let tab: Tab = {
|
||||
page: null,
|
||||
tabEl: document.getElementById("tab-" + tabID) as HTMLDivElement,
|
||||
buttonEl: document.getElementById("button-tab-" + tabID) as HTMLSpanElement,
|
||||
preFunc: preFunc,
|
||||
postFunc: postFunc,
|
||||
};
|
||||
if (this._baseOffset == -1) {
|
||||
this._baseOffset = tab.buttonEl.offsetLeft;
|
||||
}
|
||||
tab.page = {
|
||||
name: tabID,
|
||||
title: document.title, /*FIXME: Get actual names from translations*/
|
||||
url: window.URLBase + "/" + url,
|
||||
show: () => {
|
||||
tab.buttonEl.classList.add("active", "~urge");
|
||||
tab.tabEl.classList.remove("unfocused");
|
||||
tab.buttonEl.parentElement.scrollTo(tab.buttonEl.offsetLeft-this._baseOffset, 0);
|
||||
document.dispatchEvent(new CustomEvent("tab-change", { detail: tabID }));
|
||||
return true;
|
||||
},
|
||||
hide: () => {
|
||||
tab.buttonEl.classList.remove("active");
|
||||
tab.buttonEl.classList.remove("~urge");
|
||||
tab.tabEl.classList.add("unfocused");
|
||||
return true;
|
||||
},
|
||||
shouldSkip: () => false,
|
||||
};
|
||||
this.pages.setPage(tab.page);
|
||||
tab.buttonEl.onclick = () => { this.switch(tabID); };
|
||||
tab.preFunc = preFunc;
|
||||
tab.postFunc = postFunc;
|
||||
this.tabs.push(tab);
|
||||
this.tabs.set(tabID, tab);
|
||||
}
|
||||
|
||||
get current(): string { return this._current; }
|
||||
set current(tabID: string) { this.switch(tabID); }
|
||||
|
||||
switch = (tabID: string, noRun: boolean = false, keepURL: boolean = false) => {
|
||||
this._current = tabID;
|
||||
let baseOffset = -1;
|
||||
for (let t of this.tabs) {
|
||||
if (baseOffset == -1) baseOffset = t.buttonEl.offsetLeft;
|
||||
if (t.tabID == tabID) {
|
||||
t.buttonEl.classList.add("active", "~urge");
|
||||
if (t.preFunc && !noRun) { t.preFunc(); }
|
||||
t.tabEl.classList.remove("unfocused");
|
||||
if (t.postFunc && !noRun) { t.postFunc(); }
|
||||
document.dispatchEvent(new CustomEvent("tab-change", { detail: keepURL ? "" : tabID }));
|
||||
// t.buttonEl.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' })
|
||||
|
||||
t.buttonEl.parentElement.scrollTo(t.buttonEl.offsetLeft-baseOffset, 0);
|
||||
} else {
|
||||
t.buttonEl.classList.remove("active");
|
||||
t.buttonEl.classList.remove("~urge");
|
||||
t.tabEl.classList.add("unfocused");
|
||||
}
|
||||
switch = (tabID: string, noRun: boolean = false) => {
|
||||
let t = this.tabs.get(tabID);
|
||||
if (t == undefined) {
|
||||
[t] = this.tabs.values();
|
||||
}
|
||||
|
||||
this._current = t.page.name;
|
||||
|
||||
if (t.preFunc && !noRun) { t.preFunc(); }
|
||||
this.pages.load(tabID);
|
||||
if (t.postFunc && !noRun) { t.postFunc(); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user