mirror of
https://github.com/hrfee/jfa-go.git
synced 2025-01-01 05:50:12 +00:00
Compare commits
No commits in common. "591b84314809c4ea0ced183588ca5ee2b9158f49" and "47ce8a9ec4fd0a7408761d44978a93480d90bfcf" have entirely different histories.
591b843148
...
47ce8a9ec4
@ -748,18 +748,13 @@
|
|||||||
<div class="unfocused h-[100%] my-3" id="activity-not-found">
|
<div class="unfocused h-[100%] my-3" id="activity-not-found">
|
||||||
<div class="flex flex-col h-[100%] justify-center items-center">
|
<div class="flex flex-col h-[100%] justify-center items-center">
|
||||||
<span class="text-2xl font-medium italic mb-3">{{ .strings.noResultsFound }}</span>
|
<span class="text-2xl font-medium italic mb-3">{{ .strings.noResultsFound }}</span>
|
||||||
<span class="text-xl font-medium italic mb-3 unfocused" id="activity-keep-searching-description">{{ .strings.keepSearchingDescription }}</span>
|
|
||||||
<div class="flex flex-row">
|
|
||||||
<button class="button ~neutral @low activity-search-clear">
|
<button class="button ~neutral @low activity-search-clear">
|
||||||
<span class="mr-2">{{ .strings.clearSearch }}</span><i class="ri-close-line"></i>
|
<span class="mr-2">{{ .strings.clearSearch }}</span><i class="ri-close-line"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="button ~neutral @low unfocused" id="activity-keep-searching">{{ .strings.keepSearching }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button class="button m-2 ~neutral @low" id="activity-load-more">{{ .strings.loadMore }}</button>
|
<button class="button my-2 ~neutral @low" id="activity-load-more">{{ .strings.loadMore }}</button>
|
||||||
<button class="button m-2 ~neutral @low" id="activity-load-all">{{ .strings.loadAll }}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,8 +59,6 @@
|
|||||||
"disabled": "Disabled",
|
"disabled": "Disabled",
|
||||||
"sendPWR": "Send Password Reset",
|
"sendPWR": "Send Password Reset",
|
||||||
"noResultsFound": "No Results Found",
|
"noResultsFound": "No Results Found",
|
||||||
"keepSearching": "Keep Searching",
|
|
||||||
"keepSearchingDescription": "Only the current loaded activities were searched. Click below if you wish to search all activities.",
|
|
||||||
"contactThrough": "Contact through:",
|
"contactThrough": "Contact through:",
|
||||||
"extendExpiry": "Extend expiry",
|
"extendExpiry": "Extend expiry",
|
||||||
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
|
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
|
||||||
@ -171,7 +169,6 @@
|
|||||||
"inviteCreatedFilter": "Invite Created",
|
"inviteCreatedFilter": "Invite Created",
|
||||||
"inviteDeletedFilter": "Invite Deleted/Expired",
|
"inviteDeletedFilter": "Invite Deleted/Expired",
|
||||||
"loadMore": "Load More",
|
"loadMore": "Load More",
|
||||||
"loadAll": "Load All",
|
|
||||||
"noMoreResults": "No more results."
|
"noMoreResults": "No more results."
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
@ -189,8 +186,6 @@
|
|||||||
"accountConnected": "Account connected.",
|
"accountConnected": "Account connected.",
|
||||||
"referralsEnabled": "Referrals enabled.",
|
"referralsEnabled": "Referrals enabled.",
|
||||||
"activityDeleted": "Activity Deleted.",
|
"activityDeleted": "Activity Deleted.",
|
||||||
"errorInviteNoLongerExists": "Invite no longer exists.",
|
|
||||||
"errorInviteNotFound": "Invite not found.",
|
|
||||||
"errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.",
|
"errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.",
|
||||||
"errorHomescreenAppliedNoSettings": "Homescreen layout was applied, but applying settings may have failed.",
|
"errorHomescreenAppliedNoSettings": "Homescreen layout was applied, but applying settings may have failed.",
|
||||||
"errorSettingsFailed": "Application failed.",
|
"errorSettingsFailed": "Application failed.",
|
||||||
|
@ -118,9 +118,6 @@ func (app *appContext) loadRoutes(router *gin.Engine) {
|
|||||||
|
|
||||||
router.GET(p+"/accounts", app.AdminPage)
|
router.GET(p+"/accounts", app.AdminPage)
|
||||||
router.GET(p+"/settings", app.AdminPage)
|
router.GET(p+"/settings", app.AdminPage)
|
||||||
router.GET(p+"/activity", app.AdminPage)
|
|
||||||
router.GET(p+"/accounts/user/:userID", app.AdminPage)
|
|
||||||
router.GET(p+"/invites/:code", app.AdminPage)
|
|
||||||
router.GET(p+"/lang/:page/:file", app.ServeLang)
|
router.GET(p+"/lang/:page/:file", app.ServeLang)
|
||||||
router.GET(p+"/token/login", app.getTokenLogin)
|
router.GET(p+"/token/login", app.getTokenLogin)
|
||||||
router.GET(p+"/token/refresh", app.getTokenRefresh)
|
router.GET(p+"/token/refresh", app.getTokenRefresh)
|
||||||
|
21
ts/admin.ts
21
ts/admin.ts
@ -144,9 +144,6 @@ for (let tab of tabs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let isInviteURL = window.invites.isInviteURL();
|
|
||||||
let isAccountURL = accounts.isAccountURL();
|
|
||||||
|
|
||||||
// Default tab
|
// Default tab
|
||||||
if ((window.URLBase + "/").includes(window.location.pathname)) {
|
if ((window.URLBase + "/").includes(window.location.pathname)) {
|
||||||
window.tabs.switch(defaultTab.url, true);
|
window.tabs.switch(defaultTab.url, true);
|
||||||
@ -156,9 +153,7 @@ document.addEventListener("tab-change", (event: CustomEvent) => {
|
|||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const lang = urlParams.get('lang');
|
const lang = urlParams.get('lang');
|
||||||
let tab = window.URLBase + "/" + event.detail;
|
let tab = window.URLBase + "/" + event.detail;
|
||||||
if (event.detail == "") {
|
if (tab == window.URLBase + "/invites") {
|
||||||
tab = window.location.pathname;
|
|
||||||
} else if (tab == window.URLBase + "/invites") {
|
|
||||||
if (window.location.pathname == window.URLBase + "/") {
|
if (window.location.pathname == window.URLBase + "/") {
|
||||||
tab = window.URLBase + "/";
|
tab = window.URLBase + "/";
|
||||||
} else if (window.URLBase) { tab = window.URLBase; }
|
} else if (window.URLBase) { tab = window.URLBase; }
|
||||||
@ -195,20 +190,6 @@ login.onLogin = () => {
|
|||||||
case "activity": // FIXME: fix URL clash with route
|
case "activity": // FIXME: fix URL clash with route
|
||||||
activity.reload();
|
activity.reload();
|
||||||
break;
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +74,6 @@ class user implements User, SearchableItem {
|
|||||||
private _referralsEnabled: boolean;
|
private _referralsEnabled: boolean;
|
||||||
private _referralsEnabledCheck: HTMLElement;
|
private _referralsEnabledCheck: HTMLElement;
|
||||||
|
|
||||||
focus = () => this._row.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
||||||
|
|
||||||
lastNotifyMethod = (): string => {
|
lastNotifyMethod = (): string => {
|
||||||
// Telegram, Matrix, Discord
|
// Telegram, Matrix, Discord
|
||||||
const telegram = window.telegramEnabled && this._telegramUsername && this._telegramUsername != "";
|
const telegram = window.telegramEnabled && this._telegramUsername && this._telegramUsername != "";
|
||||||
@ -1680,25 +1678,6 @@ export class accountsList {
|
|||||||
this._addUserProfile.innerHTML = innerHTML;
|
this._addUserProfile.innerHTML = innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
focusAccount = (userID: string) => {
|
|
||||||
console.log("focusing user", userID);
|
|
||||||
this._searchBox.value = `id:"${userID}"`;
|
|
||||||
this._search.onSearchBoxChange();
|
|
||||||
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() {
|
constructor() {
|
||||||
this._populateNumbers();
|
this._populateNumbers();
|
||||||
this._users = {};
|
this._users = {};
|
||||||
@ -1706,7 +1685,7 @@ export class accountsList {
|
|||||||
this._selectAll.onchange = () => {
|
this._selectAll.onchange = () => {
|
||||||
this.selectAll = this._selectAll.checked;
|
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("accountCheckEvent", () => { this._checkCount++; this._checkCheckCount(); });
|
||||||
document.addEventListener("accountUncheckEvent", () => { this._checkCount--; this._checkCheckCount(); });
|
document.addEventListener("accountUncheckEvent", () => { this._checkCount--; this._checkCheckCount(); });
|
||||||
this._addUserButton.onclick = () => {
|
this._addUserButton.onclick = () => {
|
||||||
@ -1829,7 +1808,7 @@ export class accountsList {
|
|||||||
queries: this._queries,
|
queries: this._queries,
|
||||||
setVisibility: this.setVisibility,
|
setVisibility: this.setVisibility,
|
||||||
clearSearchButtonSelector: ".accounts-search-clear",
|
clearSearchButtonSelector: ".accounts-search-clear",
|
||||||
onSearchCallback: (_0: number, _1: boolean, _2: boolean) => {
|
onSearchCallback: (_0: number, _1: boolean) => {
|
||||||
this._checkCheckCount();
|
this._checkCheckCount();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1906,11 +1885,9 @@ export class accountsList {
|
|||||||
this.showHideSearchOptionsHeader();
|
this.showHideSearchOptionsHeader();
|
||||||
|
|
||||||
this._search.generateFilterList();
|
this._search.generateFilterList();
|
||||||
|
|
||||||
this.registerURLListener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reload = (callback?: () => void) => {
|
reload = () => {
|
||||||
_get("/users", null, (req: XMLHttpRequest) => {
|
_get("/users", null, (req: XMLHttpRequest) => {
|
||||||
if (req.readyState == 4 && req.status == 200) {
|
if (req.readyState == 4 && req.status == 200) {
|
||||||
// same method as inviteList.reload()
|
// same method as inviteList.reload()
|
||||||
@ -1944,16 +1921,12 @@ export class accountsList {
|
|||||||
this.setVisibility(results, true);
|
this.setVisibility(results, true);
|
||||||
}
|
}
|
||||||
this._checkCheckCount();
|
this._checkCheckCount();
|
||||||
|
|
||||||
if (callback) callback();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.loadTemplates();
|
this.loadTemplates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const accountURLEvent = (id: string) => { return new CustomEvent(accountsList._accountURLEvent, {"detail": id}) };
|
|
||||||
|
|
||||||
type GetterReturnType = Boolean | boolean | String | Number | number;
|
type GetterReturnType = Boolean | boolean | String | Number | number;
|
||||||
type Getter = () => GetterReturnType;
|
type Getter = () => GetterReturnType;
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { _post, _delete, toDateString, addLoader, removeLoader } from "../modules/common.js";
|
import { _post, _delete, toDateString, addLoader, removeLoader } from "../modules/common.js";
|
||||||
import { Search, SearchConfiguration, QueryType, SearchableItem } from "../modules/search.js";
|
import { Search, SearchConfiguration, QueryType, SearchableItem } from "../modules/search.js";
|
||||||
import { accountURLEvent } from "../modules/accounts.js";
|
|
||||||
import { inviteURLEvent } from "../modules/invites.js";
|
|
||||||
|
|
||||||
export interface activity {
|
export interface activity {
|
||||||
id: string;
|
id: string;
|
||||||
@ -44,14 +42,6 @@ export class Activity implements activity, SearchableItem {
|
|||||||
private _expiryTypeBadge: HTMLElement;
|
private _expiryTypeBadge: HTMLElement;
|
||||||
private _delete: HTMLElement;
|
private _delete: HTMLElement;
|
||||||
private _act: activity;
|
private _act: activity;
|
||||||
private _urlBase: string = ((): string => {
|
|
||||||
let link = window.location.href;
|
|
||||||
for (let split of ["#", "?", "/activity"]) {
|
|
||||||
link = link.split(split)[0];
|
|
||||||
}
|
|
||||||
if (link.slice(-1) != "/") { link += "/"; }
|
|
||||||
return link;
|
|
||||||
})();
|
|
||||||
|
|
||||||
_genUserText = (): string => {
|
_genUserText = (): string => {
|
||||||
return `<span class="font-medium">${this._act.username || this._act.user_id.substring(0, 5)}</span>`;
|
return `<span class="font-medium">${this._act.username || this._act.user_id.substring(0, 5)}</span>`;
|
||||||
@ -62,17 +52,17 @@ export class Activity implements activity, SearchableItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_genUserLink = (): string => {
|
_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 class="hover:underline" href="/accounts/user/${this._act.user_id}">${this._genUserText()}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
_genSrcUserLink = (): string => {
|
_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 class="hover:underline" href="/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 _renderInvText = (): string => { return `<span class="font-medium font-mono">${this.value || this.invite_code || "???"}</span>`; }
|
||||||
|
|
||||||
private _genInvLink = (): string => {
|
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 class="hover:underline" href="/accounts/invites/${this.invite_code}">${this._renderInvText()}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -288,30 +278,6 @@ export class Activity implements activity, SearchableItem {
|
|||||||
this._delete.addEventListener("click", this.delete);
|
this._delete.addEventListener("click", this.delete);
|
||||||
|
|
||||||
this.update(act);
|
this.update(act);
|
||||||
|
|
||||||
const pseudoUsers = this._card.getElementsByClassName("activity-pseudo-link-user") as HTMLCollectionOf<HTMLAnchorElement>;
|
|
||||||
const pseudoInvites = this._card.getElementsByClassName("activity-pseudo-link-invite") as HTMLCollectionOf<HTMLAnchorElement>;
|
|
||||||
|
|
||||||
for (let i = 0; i < pseudoUsers.length; i++) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < pseudoInvites.length; i++) {
|
|
||||||
const navigate = (event: Event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
window.tabs.switch("invites");
|
|
||||||
document.dispatchEvent(inviteURLEvent(pseudoInvites[i].getAttribute("data-id")));
|
|
||||||
window.history.pushState(null, document.title, pseudoInvites[i].getAttribute("data-href"));
|
|
||||||
}
|
|
||||||
pseudoInvites[i].onclick = navigate;
|
|
||||||
pseudoInvites[i].onkeydown = navigate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update = (act: activity) => {
|
update = (act: activity) => {
|
||||||
@ -352,11 +318,7 @@ export class activityList {
|
|||||||
private _sortDirection = document.getElementById("activity-sort-direction") as HTMLButtonElement;
|
private _sortDirection = document.getElementById("activity-sort-direction") as HTMLButtonElement;
|
||||||
private _loader = document.getElementById("activity-loader");
|
private _loader = document.getElementById("activity-loader");
|
||||||
private _loadMoreButton = document.getElementById("activity-load-more") as HTMLButtonElement;
|
private _loadMoreButton = document.getElementById("activity-load-more") as HTMLButtonElement;
|
||||||
private _loadAllButton = document.getElementById("activity-load-all") as HTMLButtonElement;
|
|
||||||
private _refreshButton = document.getElementById("activity-refresh") as HTMLButtonElement;
|
private _refreshButton = document.getElementById("activity-refresh") as HTMLButtonElement;
|
||||||
private _keepSearchingDescription = document.getElementById("activity-keep-searching-description");
|
|
||||||
private _keepSearchingButton = document.getElementById("activity-keep-searching");
|
|
||||||
|
|
||||||
private _search: Search;
|
private _search: Search;
|
||||||
private _ascending: boolean;
|
private _ascending: boolean;
|
||||||
private _hasLoaded: boolean;
|
private _hasLoaded: boolean;
|
||||||
@ -379,10 +341,6 @@ export class activityList {
|
|||||||
reload = () => {
|
reload = () => {
|
||||||
this._lastLoad = Date.now();
|
this._lastLoad = Date.now();
|
||||||
this._lastPage = false;
|
this._lastPage = false;
|
||||||
this._loadMoreButton.textContent = window.lang.strings("loadMore");
|
|
||||||
this._loadMoreButton.disabled = false;
|
|
||||||
this._loadAllButton.classList.remove("unfocused");
|
|
||||||
this._loadAllButton.disabled = false;
|
|
||||||
// this._page = 0;
|
// this._page = 0;
|
||||||
let limit = 10;
|
let limit = 10;
|
||||||
if (this._page != 0) {
|
if (this._page != 0) {
|
||||||
@ -422,23 +380,17 @@ export class activityList {
|
|||||||
|
|
||||||
if (this._search.inSearch) {
|
if (this._search.inSearch) {
|
||||||
this._search.onSearchBoxChange(true);
|
this._search.onSearchBoxChange(true);
|
||||||
this._loadAllButton.classList.remove("unfocused");
|
|
||||||
} else {
|
} else {
|
||||||
this.setVisibility(this._ordering, true);
|
this.setVisibility(this._ordering, true);
|
||||||
this._loadAllButton.classList.add("unfocused");
|
|
||||||
this._notFoundPanel.classList.add("unfocused");
|
this._notFoundPanel.classList.add("unfocused");
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMore = (callback?: () => void, loadAll: boolean = false) => {
|
loadMore = () => {
|
||||||
this._lastLoad = Date.now();
|
this._lastLoad = Date.now();
|
||||||
this._loadMoreButton.disabled = true;
|
this._loadMoreButton.disabled = true;
|
||||||
// this._loadAllButton.disabled = true;
|
const timeout = setTimeout(() => this._loadMoreButton.disabled = false, 1000);
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
this._loadMoreButton.disabled = false;
|
|
||||||
// this._loadAllButton.disabled = false;
|
|
||||||
}, 1000);
|
|
||||||
this._page += 1;
|
this._page += 1;
|
||||||
|
|
||||||
let send = {
|
let send = {
|
||||||
@ -464,8 +416,6 @@ export class activityList {
|
|||||||
if (this._lastPage) {
|
if (this._lastPage) {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
this._loadMoreButton.disabled = true;
|
this._loadMoreButton.disabled = true;
|
||||||
removeLoader(this._loadAllButton);
|
|
||||||
this._loadAllButton.classList.add("unfocused");
|
|
||||||
this._loadMoreButton.textContent = window.lang.strings("noMoreResults");
|
this._loadMoreButton.textContent = window.lang.strings("noMoreResults");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,17 +426,12 @@ export class activityList {
|
|||||||
// this._search.items = this._activities;
|
// this._search.items = this._activities;
|
||||||
// this._search.ordering = this._ordering;
|
// this._search.ordering = this._ordering;
|
||||||
|
|
||||||
if (this._search.inSearch || loadAll) {
|
if (this._search.inSearch) {
|
||||||
if (this._lastPage) {
|
this._search.onSearchBoxChange(true);
|
||||||
loadAll = false;
|
|
||||||
}
|
|
||||||
this._search.onSearchBoxChange(true, loadAll);
|
|
||||||
} else {
|
} else {
|
||||||
this.setVisibility(this._ordering, true);
|
this.setVisibility(this._ordering, true);
|
||||||
this._notFoundPanel.classList.add("unfocused");
|
this._notFoundPanel.classList.add("unfocused");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback) callback();
|
|
||||||
// removeLoader(this._loader);
|
// removeLoader(this._loader);
|
||||||
// this._activityList.classList.remove("unfocused");
|
// this._activityList.classList.remove("unfocused");
|
||||||
}, true);
|
}, true);
|
||||||
@ -618,31 +563,17 @@ export class activityList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
detectScroll = () => {
|
detectScroll = () => {
|
||||||
if (!this._hasLoaded) return;
|
|
||||||
// console.log(window.innerHeight + document.documentElement.scrollTop, document.scrollingElement.scrollHeight);
|
// console.log(window.innerHeight + document.documentElement.scrollTop, document.scrollingElement.scrollHeight);
|
||||||
if (Math.abs(window.innerHeight + document.documentElement.scrollTop - document.scrollingElement.scrollHeight) < 50) {
|
if (Math.abs(window.innerHeight + document.documentElement.scrollTop - document.scrollingElement.scrollHeight) < 50) {
|
||||||
// window.notifications.customSuccess("scroll", "Reached bottom.");
|
// window.notifications.customSuccess("scroll", "Reached bottom.");
|
||||||
// Wait .5s between loads
|
// Wait 1s between loads
|
||||||
if (this._lastLoad + 500 > Date.now()) return;
|
if (this._lastLoad + 1000 > Date.now()) return;
|
||||||
this.loadMore();
|
this.loadMore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _prevResultCount = 0;
|
private _prevResultCount = 0;
|
||||||
|
|
||||||
private _notFoundCallback = (notFound: boolean) => {
|
|
||||||
if (notFound) this._loadMoreButton.classList.add("unfocused");
|
|
||||||
else this._loadMoreButton.classList.remove("unfocused");
|
|
||||||
|
|
||||||
if (notFound && !this._lastPage) {
|
|
||||||
this._keepSearchingButton.classList.remove("unfocused");
|
|
||||||
this._keepSearchingDescription.classList.remove("unfocused");
|
|
||||||
} else {
|
|
||||||
this._keepSearchingButton.classList.add("unfocused");
|
|
||||||
this._keepSearchingDescription.classList.add("unfocused");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._activityList = document.getElementById("activity-card-list");
|
this._activityList = document.getElementById("activity-card-list");
|
||||||
document.addEventListener("activity-reload", this.reload);
|
document.addEventListener("activity-reload", this.reload);
|
||||||
@ -657,13 +588,10 @@ export class activityList {
|
|||||||
queries: this._queries,
|
queries: this._queries,
|
||||||
setVisibility: this.setVisibility,
|
setVisibility: this.setVisibility,
|
||||||
filterList: document.getElementById("activity-filter-list"),
|
filterList: document.getElementById("activity-filter-list"),
|
||||||
// notFoundCallback: this._notFoundCallback,
|
onSearchCallback: (visibleCount: number, newItems: boolean) => {
|
||||||
onSearchCallback: (visibleCount: number, newItems: boolean, loadAll: boolean) => {
|
|
||||||
if (this._search.inSearch && !this._lastPage) this._loadAllButton.classList.remove("unfocused");
|
|
||||||
else this._loadAllButton.classList.add("unfocused");
|
|
||||||
|
|
||||||
if (visibleCount < 10) {
|
if (visibleCount < 10) {
|
||||||
if (!newItems || this._prevResultCount != visibleCount || (visibleCount == 0 && !this._lastPage) || loadAll) this.loadMore(() => {}, loadAll);
|
if (!newItems || this._prevResultCount != visibleCount || (visibleCount == 0 && !this._lastPage)) this.loadMore();
|
||||||
}
|
}
|
||||||
this._prevResultCount = visibleCount;
|
this._prevResultCount = visibleCount;
|
||||||
}
|
}
|
||||||
@ -675,15 +603,7 @@ export class activityList {
|
|||||||
this.ascending = false;
|
this.ascending = false;
|
||||||
this._sortDirection.addEventListener("click", () => this.ascending = !this.ascending);
|
this._sortDirection.addEventListener("click", () => this.ascending = !this.ascending);
|
||||||
|
|
||||||
this._loadMoreButton.onclick = () => this.loadMore();
|
this._loadMoreButton.onclick = this.loadMore;
|
||||||
this._loadAllButton.onclick = () => {
|
|
||||||
addLoader(this._loadAllButton, true);
|
|
||||||
this.loadMore(() => {}, true);
|
|
||||||
};
|
|
||||||
/* this._keepSearchingButton.onclick = () => {
|
|
||||||
addLoader(this._keepSearchingButton, true);
|
|
||||||
this.loadMore(() => removeLoader(this._keepSearchingButton, true));
|
|
||||||
}; */
|
|
||||||
this._refreshButton.onclick = this.reload;
|
this._refreshButton.onclick = this.reload;
|
||||||
|
|
||||||
window.onscroll = this.detectScroll;
|
window.onscroll = this.detectScroll;
|
||||||
|
@ -261,8 +261,6 @@ class DOMInvite implements Invite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
focus = () => this._container.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
||||||
|
|
||||||
constructor(invite: Invite) {
|
constructor(invite: Invite) {
|
||||||
// first create the invite structure, then use our setter methods to fill in the data.
|
// first create the invite structure, then use our setter methods to fill in the data.
|
||||||
this._container = document.createElement('div') as HTMLDivElement;
|
this._container = document.createElement('div') as HTMLDivElement;
|
||||||
@ -425,26 +423,6 @@ export class inviteList implements inviteList {
|
|||||||
|
|
||||||
invites: { [code: string]: DOMInvite };
|
invites: { [code: string]: DOMInvite };
|
||||||
|
|
||||||
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", 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() {
|
constructor() {
|
||||||
this._list = document.getElementById('invites') as HTMLDivElement;
|
this._list = document.getElementById('invites') as HTMLDivElement;
|
||||||
this.empty = true;
|
this.empty = true;
|
||||||
@ -458,8 +436,6 @@ export class inviteList implements inviteList {
|
|||||||
this.empty = true;
|
this.empty = true;
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
this.registerURLListener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get empty(): boolean { return this._empty; }
|
get empty(): boolean { return this._empty; }
|
||||||
@ -492,7 +468,7 @@ export class inviteList implements inviteList {
|
|||||||
this._list.appendChild(domInv.asElement());
|
this._list.appendChild(domInv.asElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
reload = (callback?: () => void) => _get("/invites", null, (req: XMLHttpRequest) => {
|
reload = () => _get("/invites", null, (req: XMLHttpRequest) => {
|
||||||
if (req.readyState == 4) {
|
if (req.readyState == 4) {
|
||||||
let data = req.response;
|
let data = req.response;
|
||||||
if (req.status == 200) {
|
if (req.status == 200) {
|
||||||
@ -521,13 +497,10 @@ export class inviteList implements inviteList {
|
|||||||
this.invites[code].remove();
|
this.invites[code].remove();
|
||||||
delete this.invites[code];
|
delete this.invites[code];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callback) callback();
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const inviteURLEvent = (id: string) => { return new CustomEvent(inviteList._inviteURLEvent, {"detail": id}) };
|
|
||||||
|
|
||||||
function parseInvite(invite: { [f: string]: string | number | { [name: string]: number } | boolean }): Invite {
|
function parseInvite(invite: { [f: string]: string | number | { [name: string]: number } | boolean }): Invite {
|
||||||
let parsed: Invite = {};
|
let parsed: Invite = {};
|
||||||
|
@ -16,13 +16,12 @@ export interface SearchConfiguration {
|
|||||||
sortingByButton: HTMLButtonElement;
|
sortingByButton: HTMLButtonElement;
|
||||||
searchOptionsHeader: HTMLElement;
|
searchOptionsHeader: HTMLElement;
|
||||||
notFoundPanel: HTMLElement;
|
notFoundPanel: HTMLElement;
|
||||||
notFoundCallback?: (notFound: boolean) => void;
|
|
||||||
filterList: HTMLElement;
|
filterList: HTMLElement;
|
||||||
clearSearchButtonSelector: string;
|
clearSearchButtonSelector: string;
|
||||||
search: HTMLInputElement;
|
search: HTMLInputElement;
|
||||||
queries: { [field: string]: QueryType };
|
queries: { [field: string]: QueryType };
|
||||||
setVisibility: (items: string[], visible: boolean) => void;
|
setVisibility: (items: string[], visible: boolean) => void;
|
||||||
onSearchCallback: (visibleCount: number, newItems: boolean, loadAll: boolean) => void;
|
onSearchCallback: (visibleCount: number, newItems: boolean) => void;
|
||||||
loadMore?: () => void;
|
loadMore?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +268,7 @@ export class Search {
|
|||||||
get ordering(): string[] { return this._ordering; }
|
get ordering(): string[] { return this._ordering; }
|
||||||
set ordering(v: string[]) { this._ordering = v; }
|
set ordering(v: string[]) { this._ordering = v; }
|
||||||
|
|
||||||
onSearchBoxChange = (newItems: boolean = false, loadAll: boolean = false) => {
|
onSearchBoxChange = (newItems: boolean = false) => {
|
||||||
const query = this._c.search.value;
|
const query = this._c.search.value;
|
||||||
if (!query) {
|
if (!query) {
|
||||||
this.inSearch = false;
|
this.inSearch = false;
|
||||||
@ -278,14 +277,13 @@ export class Search {
|
|||||||
}
|
}
|
||||||
const results = this.search(query);
|
const results = this.search(query);
|
||||||
this._c.setVisibility(results, true);
|
this._c.setVisibility(results, true);
|
||||||
this._c.onSearchCallback(results.length, newItems, loadAll);
|
this._c.onSearchCallback(results.length, newItems);
|
||||||
this.showHideSearchOptionsHeader();
|
this.showHideSearchOptionsHeader();
|
||||||
if (results.length == 0) {
|
if (results.length == 0) {
|
||||||
this._c.notFoundPanel.classList.remove("unfocused");
|
this._c.notFoundPanel.classList.remove("unfocused");
|
||||||
} else {
|
} else {
|
||||||
this._c.notFoundPanel.classList.add("unfocused");
|
this._c.notFoundPanel.classList.add("unfocused");
|
||||||
}
|
}
|
||||||
if (this._c.notFoundCallback) this._c.notFoundCallback(results.length == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fillInFilter = (name: string, value: string, offset?: number) => {
|
fillInFilter = (name: string, value: string, offset?: number) => {
|
||||||
|
@ -20,7 +20,7 @@ export class Tabs implements Tabs {
|
|||||||
get current(): string { return this._current; }
|
get current(): string { return this._current; }
|
||||||
set current(tabID: string) { this.switch(tabID); }
|
set current(tabID: string) { this.switch(tabID); }
|
||||||
|
|
||||||
switch = (tabID: string, noRun: boolean = false, keepURL: boolean = false) => {
|
switch = (tabID: string, noRun: boolean = false) => {
|
||||||
this._current = tabID;
|
this._current = tabID;
|
||||||
for (let t of this.tabs) {
|
for (let t of this.tabs) {
|
||||||
if (t.tabID == tabID) {
|
if (t.tabID == tabID) {
|
||||||
@ -28,7 +28,7 @@ export class Tabs implements Tabs {
|
|||||||
if (t.preFunc && !noRun) { t.preFunc(); }
|
if (t.preFunc && !noRun) { t.preFunc(); }
|
||||||
t.tabEl.classList.remove("unfocused");
|
t.tabEl.classList.remove("unfocused");
|
||||||
if (t.postFunc && !noRun) { t.postFunc(); }
|
if (t.postFunc && !noRun) { t.postFunc(); }
|
||||||
document.dispatchEvent(new CustomEvent("tab-change", { detail: keepURL ? "" : tabID }));
|
document.dispatchEvent(new CustomEvent("tab-change", { detail: tabID }));
|
||||||
} else {
|
} else {
|
||||||
t.buttonEl.classList.remove("active");
|
t.buttonEl.classList.remove("active");
|
||||||
t.buttonEl.classList.remove("~urge");
|
t.buttonEl.classList.remove("~urge");
|
||||||
|
@ -80,7 +80,7 @@ declare interface Tabs {
|
|||||||
current: string;
|
current: string;
|
||||||
tabs: Array<Tab>;
|
tabs: Array<Tab>;
|
||||||
addTab: (tabID: string, preFunc?: () => void, postFunc?: () => void) => void;
|
addTab: (tabID: string, preFunc?: () => void, postFunc?: () => void) => void;
|
||||||
switch: (tabID: string, noRun?: boolean, keepURL?: boolean) => void;
|
switch: (tabID: string, noRun?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface Tab {
|
declare interface Tab {
|
||||||
@ -139,9 +139,7 @@ interface inviteList {
|
|||||||
empty: boolean;
|
empty: boolean;
|
||||||
invites: { [code: string]: Invite }
|
invites: { [code: string]: Invite }
|
||||||
add: (invite: Invite) => void;
|
add: (invite: Invite) => void;
|
||||||
reload: (callback?: () => void) => void;
|
reload: () => void;
|
||||||
isInviteURL: () => boolean;
|
|
||||||
loadInviteURL: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally added to typescript, dont need this anymore.
|
// Finally added to typescript, dont need this anymore.
|
||||||
|
4
views.go
4
views.go
@ -39,10 +39,6 @@ func (app *appContext) loadCSSHeader() string {
|
|||||||
|
|
||||||
func (app *appContext) getURLBase(gc *gin.Context) string {
|
func (app *appContext) getURLBase(gc *gin.Context) string {
|
||||||
if strings.HasPrefix(gc.Request.URL.String(), app.URLBase) {
|
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 app.URLBase
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
Loading…
Reference in New Issue
Block a user