mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 17:10:10 +00:00
activity: pseudo links work on click
This commit is contained in:
parent
d00f3fcfbc
commit
0238c6778c
@ -186,6 +186,7 @@
|
|||||||
"accountConnected": "Account connected.",
|
"accountConnected": "Account connected.",
|
||||||
"referralsEnabled": "Referrals enabled.",
|
"referralsEnabled": "Referrals enabled.",
|
||||||
"activityDeleted": "Activity Deleted.",
|
"activityDeleted": "Activity Deleted.",
|
||||||
|
"errorInviteDoesntExist": "Invite no longer exists.",
|
||||||
"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.",
|
||||||
|
@ -119,6 +119,8 @@ 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+"/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)
|
||||||
|
@ -74,6 +74,8 @@ 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 != "";
|
||||||
@ -1678,6 +1680,14 @@ export class accountsList {
|
|||||||
this._addUserProfile.innerHTML = innerHTML;
|
this._addUserProfile.innerHTML = innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly _accountURLEvent = "account-url";
|
||||||
|
registerURLListener = () => document.addEventListener(accountsList._accountURLEvent, (event: CustomEvent) => {
|
||||||
|
const userID = event.detail;
|
||||||
|
this._searchBox.value = `id:"${userID}"`;
|
||||||
|
this._search.onSearchBoxChange();
|
||||||
|
this._users[userID].focus();
|
||||||
|
});
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._populateNumbers();
|
this._populateNumbers();
|
||||||
this._users = {};
|
this._users = {};
|
||||||
@ -1885,6 +1895,8 @@ export class accountsList {
|
|||||||
this.showHideSearchOptionsHeader();
|
this.showHideSearchOptionsHeader();
|
||||||
|
|
||||||
this._search.generateFilterList();
|
this._search.generateFilterList();
|
||||||
|
|
||||||
|
this.registerURLListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
reload = () => {
|
reload = () => {
|
||||||
@ -1927,6 +1939,8 @@ export class accountsList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,5 +1,7 @@
|
|||||||
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;
|
||||||
@ -42,6 +44,14 @@ 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>`;
|
||||||
@ -52,17 +62,17 @@ export class Activity implements activity, SearchableItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_genUserLink = (): string => {
|
_genUserLink = (): string => {
|
||||||
return `<a class="hover:underline" href="/accounts/user/${this._act.user_id}">${this._genUserText()}</a>`;
|
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>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
_genSrcUserLink = (): string => {
|
_genSrcUserLink = (): string => {
|
||||||
return `<a class="hover:underline" href="/accounts/user/${this._act.source}">${this._genSrcUserText()}</a>`;
|
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>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 `<a class="hover:underline" href="/accounts/invites/${this.invite_code}">${this._renderInvText()}</a>`;
|
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>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -278,6 +288,30 @@ 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) => {
|
||||||
|
@ -261,6 +261,8 @@ 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;
|
||||||
@ -423,6 +425,16 @@ export class inviteList implements inviteList {
|
|||||||
|
|
||||||
invites: { [code: string]: DOMInvite };
|
invites: { [code: string]: DOMInvite };
|
||||||
|
|
||||||
|
public static readonly _inviteURLEvent = "invite-url";
|
||||||
|
registerURLListener = () => document.addEventListener(inviteList._inviteURLEvent, (event: CustomEvent) => {
|
||||||
|
const inviteCode = event.detail;
|
||||||
|
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"));
|
||||||
|
})
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._list = document.getElementById('invites') as HTMLDivElement;
|
this._list = document.getElementById('invites') as HTMLDivElement;
|
||||||
this.empty = true;
|
this.empty = true;
|
||||||
@ -436,6 +448,8 @@ 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; }
|
||||||
@ -501,6 +515,7 @@ export class inviteList implements inviteList {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = {};
|
||||||
|
Loading…
Reference in New Issue
Block a user