invites: add /invites/send, store more details in new SentTo field
deprecated SendTo string field for SentTo, which holds successful send addresses, and failures with a reason that isn't plain text. Will soon add an interface for sending invites after their creation. For #444 (ha).
This commit is contained in:
@@ -1247,6 +1247,12 @@ export class accountsList extends PaginatedList {
|
||||
this._search.showHideSearchOptionsHeader();
|
||||
|
||||
this.registerURLListener();
|
||||
|
||||
// Get rid of nasty CSS
|
||||
window.modals.announce.onclose = () => {
|
||||
const preview = document.getElementById("announce-preview") as HTMLDivElement;
|
||||
preview.textContent = ``;
|
||||
}
|
||||
}
|
||||
|
||||
reload = (callback?: (resp: paginatedDTO) => void) => {
|
||||
|
||||
+45
-7
@@ -123,20 +123,55 @@ class DOMInvite implements Invite {
|
||||
} else {
|
||||
chip.classList.add("button");
|
||||
chip.parentElement.classList.add("h-full");
|
||||
if (address.includes("Failed")) {
|
||||
if (address.includes(window.lang.strings("failed"))) {
|
||||
icon.classList.remove("ri-mail-line");
|
||||
icon.classList.add("ri-mail-close-line");
|
||||
chip.classList.remove("~neutral");
|
||||
chip.classList.add("~critical");
|
||||
} else {
|
||||
address = "Sent to " + address;
|
||||
icon.classList.remove("ri-mail-close-line");
|
||||
icon.classList.add("ri-mail-line");
|
||||
chip.classList.remove("~critical");
|
||||
chip.classList.add("~neutral");
|
||||
}
|
||||
}
|
||||
tooltip.textContent = address;
|
||||
// innerHTML as the newer sent_to re-uses this with HTML.
|
||||
tooltip.innerHTML = address;
|
||||
}
|
||||
|
||||
private _sent_to: SentToList;
|
||||
get sent_to(): SentToList { return this._sent_to; }
|
||||
set sent_to(v: SentToList) {
|
||||
this._sent_to = v;
|
||||
if (!v || !(v.success || v.failed)) return;
|
||||
let text = "";
|
||||
if (v.success && v.success.length > 0) {
|
||||
text += window.lang.strings("sentTo") + ": " + v.success.join(", ") + " <br>"
|
||||
}
|
||||
if (v.failed && v.failed.length > 0) {
|
||||
text += window.lang.strings("failed") + ": " + v.failed.map((el: SendFailure) => {
|
||||
let err: string;
|
||||
switch (el.reason) {
|
||||
case "CheckLogs":
|
||||
err = window.lang.notif("errorCheckLogs");
|
||||
break;
|
||||
case "NoUser":
|
||||
err = window.lang.notif("errorNoUser");
|
||||
break;
|
||||
case "MultiUser":
|
||||
err = window.lang.notif("errorMultiUser");
|
||||
break;
|
||||
case "InvalidAddress":
|
||||
err = window.lang.notif("errorInvalidAddress");
|
||||
break;
|
||||
default:
|
||||
err = el.reason;
|
||||
break;
|
||||
}
|
||||
return el.address + " (" + err + ")";
|
||||
}).join(", ");
|
||||
}
|
||||
if (text.length != 0) this.send_to = text;
|
||||
}
|
||||
|
||||
private _usedBy: { [name: string]: number };
|
||||
@@ -455,6 +490,7 @@ class DOMInvite implements Invite {
|
||||
this.code = invite.code;
|
||||
this.created = invite.created;
|
||||
this.send_to = invite.send_to;
|
||||
this.sent_to = invite.sent_to;
|
||||
this.expiresIn = invite.expiresIn;
|
||||
if (window.notificationsEnabled) {
|
||||
this.notifyCreation = invite.notifyCreation;
|
||||
@@ -477,7 +513,7 @@ class DOMInvite implements Invite {
|
||||
remove = () => { this._container.remove(); }
|
||||
}
|
||||
|
||||
export class inviteList implements inviteList {
|
||||
export class DOMInviteList implements InviteList {
|
||||
private _list: HTMLDivElement;
|
||||
private _empty: boolean;
|
||||
// since invite reload sends profiles, this event it broadcast so the createInvite object can load them.
|
||||
@@ -493,7 +529,7 @@ export class inviteList implements inviteList {
|
||||
};
|
||||
|
||||
public static readonly _inviteURLEvent = "invite-url";
|
||||
registerURLListener = () => document.addEventListener(inviteList._inviteURLEvent, (event: CustomEvent) => {
|
||||
registerURLListener = () => document.addEventListener(DOMInviteList._inviteURLEvent, (event: CustomEvent) => {
|
||||
this.focusInvite(event.detail);
|
||||
})
|
||||
|
||||
@@ -587,12 +623,14 @@ export class inviteList implements inviteList {
|
||||
}));
|
||||
}
|
||||
|
||||
export const inviteURLEvent = (id: string) => { return new CustomEvent(inviteList._inviteURLEvent, {"detail": id}) };
|
||||
export const inviteURLEvent = (id: string) => { return new CustomEvent(DOMInviteList._inviteURLEvent, {"detail": id}) };
|
||||
|
||||
function parseInvite(invite: { [f: string]: string | number | { [name: string]: number } | boolean }): Invite {
|
||||
// FIXME: Please, i beg you, get rid of this horror!
|
||||
function parseInvite(invite: { [f: string]: string | number | { [name: string]: number } | boolean | SentToList }): Invite {
|
||||
let parsed: Invite = {};
|
||||
parsed.code = invite["code"] as string;
|
||||
parsed.send_to = invite["send_to"] as string || "";
|
||||
parsed.sent_to = invite["sent_to"] as SentToList || null;
|
||||
parsed.label = invite["label"] as string || "";
|
||||
parsed.user_label = invite["user_label"] as string || "";
|
||||
let time = "";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { _get } from "../modules/common.js";
|
||||
import { Template } from "@hrfee/simpletemplate";
|
||||
|
||||
interface Meta {
|
||||
name: string;
|
||||
@@ -39,6 +40,15 @@ export class lang implements Lang {
|
||||
return str;
|
||||
}
|
||||
|
||||
template = (sect: string, key: string, subs: { [key: string]: any }): string => {
|
||||
if (sect == "quantityStrings" || sect == "meta") { return ""; }
|
||||
const map = new Map<string, any>();
|
||||
for (let key of Object.keys(subs)) { map.set(key, subs[key]); }
|
||||
const [out, err] = Template(this._lang[sect][key], map);
|
||||
if (err != null) throw err;
|
||||
return out;
|
||||
}
|
||||
|
||||
quantity = (key: string, number: number): string => {
|
||||
if (number == 1) {
|
||||
return this._lang.quantityStrings[key].singular.replace("{n}", ""+number)
|
||||
|
||||
+16
-1
@@ -1626,7 +1626,8 @@ class MessageEditor {
|
||||
} else {
|
||||
for (let i = this._templ.conditionals.length-1; i >= 0; i--) {
|
||||
let ci = i % colors.length;
|
||||
innerHTML += '<span class="button ~' + colors[ci] +' @low mb-4" style="margin-left: 0.25rem; margin-right: 0.25rem;"></span>'
|
||||
// FIXME: Store full color strings (with ~) so tailwind sees them.
|
||||
innerHTML += '<span class="button ~' + colors[ci] +' @low"></span>'
|
||||
}
|
||||
this._conditionalsLabel.classList.remove("unfocused");
|
||||
this._conditionals.innerHTML = innerHTML
|
||||
@@ -1754,6 +1755,20 @@ class MessageEditor {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const descriptions = document.getElementsByClassName("editor-syntax-description") as HTMLCollectionOf<HTMLParagraphElement>;
|
||||
for (let el of descriptions) {
|
||||
el.innerHTML = window.lang.template("strings", "syntaxDescription", {
|
||||
"variable": `<span class="font-mono font-bold">{varname}</span>`,
|
||||
"ifTruth": `<span class="font-mono font-bold">{if address}Message sent to {address}{end}</span>`,
|
||||
"ifCompare": `<span class="font-mono font-bold">{if profile == "Friends"}Friend{else if profile != "Admins"}User{end}</span>`
|
||||
});
|
||||
};
|
||||
|
||||
// Get rid of nasty CSS
|
||||
window.modals.editor.onclose = () => {
|
||||
this._preview.textContent = ``;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user