diff --git a/lang/admin/en-us.json b/lang/admin/en-us.json index 20b00ea..bf95874 100644 --- a/lang/admin/en-us.json +++ b/lang/admin/en-us.json @@ -186,7 +186,8 @@ "accountConnected": "Account connected.", "referralsEnabled": "Referrals enabled.", "activityDeleted": "Activity Deleted.", - "errorInviteDoesntExist": "Invite no longer exists.", + "errorInviteNoLongerExists": "Invite no longer exists.", + "errorInviteNotFound": "Invite not found.", "errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.", "errorHomescreenAppliedNoSettings": "Homescreen layout was applied, but applying settings may have failed.", "errorSettingsFailed": "Application failed.", diff --git a/ts/admin.ts b/ts/admin.ts index 1a8109f..5edce5b 100644 --- a/ts/admin.ts +++ b/ts/admin.ts @@ -144,6 +144,9 @@ for (let tab of tabs) { } } +let isInviteURL = window.invites.isInviteURL(); +let isAccountURL = accounts.isAccountURL(); + // Default tab if ((window.URLBase + "/").includes(window.location.pathname)) { window.tabs.switch(defaultTab.url, true); @@ -153,7 +156,9 @@ document.addEventListener("tab-change", (event: CustomEvent) => { const urlParams = new URLSearchParams(window.location.search); const lang = urlParams.get('lang'); let tab = window.URLBase + "/" + event.detail; - if (tab == window.URLBase + "/invites") { + if (event.detail == "") { + tab = window.location.pathname; + } else if (tab == window.URLBase + "/invites") { if (window.location.pathname == window.URLBase + "/") { tab = window.URLBase + "/"; } else if (window.URLBase) { tab = window.URLBase; } @@ -190,6 +195,20 @@ login.onLogin = () => { case "activity": // FIXME: fix URL clash with route activity.reload(); break; + default: + console.log(isAccountURL, isInviteURL); + if (isInviteURL) { + window.invites.reload(() => { + window.invites.loadInviteURL(); + window.tabs.switch("invites", false, true); + }); + } else if (isAccountURL) { + accounts.reload(() => { + accounts.loadAccountURL(); + window.tabs.switch("accounts", false, true); + }); + } + break; } } diff --git a/ts/modules/accounts.ts b/ts/modules/accounts.ts index f2850b3..5bd9d14 100644 --- a/ts/modules/accounts.ts +++ b/ts/modules/accounts.ts @@ -1680,14 +1680,25 @@ export class accountsList { this._addUserProfile.innerHTML = innerHTML; } - public static readonly _accountURLEvent = "account-url"; - registerURLListener = () => document.addEventListener(accountsList._accountURLEvent, (event: CustomEvent) => { - const userID = event.detail; + focusAccount = (userID: string) => { + console.log("focusing user", userID); this._searchBox.value = `id:"${userID}"`; this._search.onSearchBoxChange(); - this._users[userID].focus(); + if (userID in this._users) this._users[userID].focus(); + } + + public static readonly _accountURLEvent = "account-url"; + registerURLListener = () => document.addEventListener(accountsList._accountURLEvent, (event: CustomEvent) => { + this.focusAccount(event.detail); }); + isAccountURL = () => { return window.location.pathname.startsWith(window.URLBase + "/accounts/user/"); } + + loadAccountURL = () => { + let userID = window.location.pathname.split(window.URLBase + "/accounts/user/")[1].split("?lang")[0]; + this.focusAccount(userID); + } + constructor() { this._populateNumbers(); this._users = {}; @@ -1695,7 +1706,7 @@ export class accountsList { this._selectAll.onchange = () => { this.selectAll = this._selectAll.checked; }; - document.addEventListener("accounts-reload", this.reload); + document.addEventListener("accounts-reload", () => this.reload()); document.addEventListener("accountCheckEvent", () => { this._checkCount++; this._checkCheckCount(); }); document.addEventListener("accountUncheckEvent", () => { this._checkCount--; this._checkCheckCount(); }); this._addUserButton.onclick = () => { @@ -1899,7 +1910,7 @@ export class accountsList { this.registerURLListener(); } - reload = () => { + reload = (callback?: () => void) => { _get("/users", null, (req: XMLHttpRequest) => { if (req.readyState == 4 && req.status == 200) { // same method as inviteList.reload() @@ -1933,6 +1944,8 @@ export class accountsList { this.setVisibility(results, true); } this._checkCheckCount(); + + if (callback) callback(); } }); this.loadTemplates(); diff --git a/ts/modules/activity.ts b/ts/modules/activity.ts index 392d005..10fa9aa 100644 --- a/ts/modules/activity.ts +++ b/ts/modules/activity.ts @@ -597,6 +597,7 @@ export class activityList { } detectScroll = () => { + if (!this._hasLoaded) return; // console.log(window.innerHeight + document.documentElement.scrollTop, document.scrollingElement.scrollHeight); if (Math.abs(window.innerHeight + document.documentElement.scrollTop - document.scrollingElement.scrollHeight) < 50) { // window.notifications.customSuccess("scroll", "Reached bottom."); diff --git a/ts/modules/invites.ts b/ts/modules/invites.ts index fb52be4..cb09368 100644 --- a/ts/modules/invites.ts +++ b/ts/modules/invites.ts @@ -425,16 +425,26 @@ export class inviteList implements inviteList { invites: { [code: string]: DOMInvite }; - public static readonly _inviteURLEvent = "invite-url"; - registerURLListener = () => document.addEventListener(inviteList._inviteURLEvent, (event: CustomEvent) => { - const inviteCode = event.detail; + focusInvite = (inviteCode: string, errorMsg: string = window.lang.notif("errorInviteNoLongerExists")) => { for (let code of Object.keys(this.invites)) { this.invites[code].expanded = code == inviteCode; } if (inviteCode in this.invites) this.invites[inviteCode].focus(); - else window.notifications.customError("inviteDoesntExistError", window.lang.notif("errorInviteDoesntExist")); + else window.notifications.customError("inviteDoesntExistError", errorMsg); + }; + + public static readonly _inviteURLEvent = "invite-url"; + registerURLListener = () => document.addEventListener(inviteList._inviteURLEvent, (event: CustomEvent) => { + this.focusInvite(event.detail); }) + isInviteURL = () => { return window.location.pathname.startsWith(window.URLBase + "/invites/"); } + + loadInviteURL = () => { + let inviteCode = window.location.pathname.split(window.URLBase + "/invites/")[1].split("?lang")[0]; + this.focusInvite(inviteCode, window.lang.notif("errorInviteNotFound")); + } + constructor() { this._list = document.getElementById('invites') as HTMLDivElement; this.empty = true; @@ -482,7 +492,7 @@ export class inviteList implements inviteList { this._list.appendChild(domInv.asElement()); } - reload = () => _get("/invites", null, (req: XMLHttpRequest) => { + reload = (callback?: () => void) => _get("/invites", null, (req: XMLHttpRequest) => { if (req.readyState == 4) { let data = req.response; if (req.status == 200) { @@ -511,6 +521,8 @@ export class inviteList implements inviteList { this.invites[code].remove(); delete this.invites[code]; } + + if (callback) callback(); } }) } diff --git a/ts/modules/tabs.ts b/ts/modules/tabs.ts index 8f862e8..4d84685 100644 --- a/ts/modules/tabs.ts +++ b/ts/modules/tabs.ts @@ -20,7 +20,7 @@ export class Tabs implements Tabs { get current(): string { return this._current; } set current(tabID: string) { this.switch(tabID); } - switch = (tabID: string, noRun: boolean = false) => { + switch = (tabID: string, noRun: boolean = false, keepURL: boolean = false) => { this._current = tabID; for (let t of this.tabs) { if (t.tabID == tabID) { @@ -28,7 +28,7 @@ export class Tabs implements Tabs { if (t.preFunc && !noRun) { t.preFunc(); } t.tabEl.classList.remove("unfocused"); if (t.postFunc && !noRun) { t.postFunc(); } - document.dispatchEvent(new CustomEvent("tab-change", { detail: tabID })); + document.dispatchEvent(new CustomEvent("tab-change", { detail: keepURL ? "" : tabID })); } else { t.buttonEl.classList.remove("active"); t.buttonEl.classList.remove("~urge"); diff --git a/ts/typings/d.ts b/ts/typings/d.ts index 8d97410..0270412 100644 --- a/ts/typings/d.ts +++ b/ts/typings/d.ts @@ -80,7 +80,7 @@ declare interface Tabs { current: string; tabs: Array; addTab: (tabID: string, preFunc?: () => void, postFunc?: () => void) => void; - switch: (tabID: string, noRun?: boolean) => void; + switch: (tabID: string, noRun?: boolean, keepURL?: boolean) => void; } declare interface Tab { @@ -139,7 +139,9 @@ interface inviteList { empty: boolean; invites: { [code: string]: Invite } add: (invite: Invite) => void; - reload: () => void; + reload: (callback?: () => void) => void; + isInviteURL: () => boolean; + loadInviteURL: () => void; } // Finally added to typescript, dont need this anymore. diff --git a/views.go b/views.go index 2d91e21..398f64a 100644 --- a/views.go +++ b/views.go @@ -39,6 +39,10 @@ func (app *appContext) loadCSSHeader() string { func (app *appContext) getURLBase(gc *gin.Context) string { if strings.HasPrefix(gc.Request.URL.String(), app.URLBase) { + // Hack to fix the common URL base /accounts + if app.URLBase == "/accounts" && strings.HasPrefix(gc.Request.URL.String(), "/accounts/user/") { + return "" + } return app.URLBase } return ""