返回提交历史
Modified
src/controllers/custom/createMessageController.ts
+10
-3
Modified
static/webui/index.html
+47
-0
Modified
static/webui/script.js
+136
-0
Modified
static/webui/translations/de.js
+22
-0
Modified
static/webui/translations/en.js
+22
-0
Modified
static/webui/translations/es.js
+22
-0
Modified
static/webui/translations/fr.js
+22
-0
Modified
static/webui/translations/ru.js
+22
-0
Modified
static/webui/translations/uk.js
+22
-0
Modified
static/webui/translations/zh.js
+22
-0
XFEstudio/XFESpaceNinjaServer
feat(webui): "broadcast inbox message" for admins (#3987)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/3987 Reviewed-by: Sainan <63328889+sainan@users.noreply.github.com> Co-authored-by: Drake <kuzuriyager@gmail.com> Co-committed-by: Drake <kuzuriyager@gmail.com>
00cece0f
代码差异
10 个文件
+347
-3
@@ -1,15 +1,22 @@
1
1
import type { IMessageCreationTemplate } from "../../services/inboxService.ts";
2
2
import { createMessage } from "../../services/inboxService.ts";
3
import { getAccountForRequest, isAdministrator } from "../../services/loginService.ts";
3
4
import type { RequestHandler } from "express";
4
5
5
6
export const createMessageController: RequestHandler = async (req, res) => {
6
7
const message = req.body as (IMessageCreationTemplate & { ownerId: string })[] | undefined;
7
8
8
if (!message) {
9
const account = await getAccountForRequest(req);
10
if (!isAdministrator(account)) {
11
res.status(401).end();
12
return;
13
}
14
15
if (!Array.isArray(message) || message.length === 0) {
9
16
res.status(400).send("No message provided");
10
17
return;
11
18
}
12
const savedMessages = await createMessage(message[0].ownerId, message);
19
await createMessage(message[0].ownerId, message);
13
20
14
res.json(savedMessages);
21
res.status(204).end();
15
22
};
@@ -1731,6 +1731,53 @@
1731
1731
</table>
1732
1732
</div>
1733
1733
</div>
1734
<div class="card mt-3">
1735
<h5 class="card-header" data-loc="admin_broadcastInbox"></h5>
1736
<div class="card-body">
1737
<div class="row g-2 mb-2">
1738
<div class="col-md-4">
1739
<label class="form-label" for="admin-message-target-mode" data-loc="admin_messageTargetMode"></label>
1740
<select class="form-select" id="admin-message-target-mode" onchange="onAdminMessageTargetModeChange();">
1741
<option value="all" data-loc="admin_messageTargetAll"></option>
1742
<option value="specific" data-loc="admin_messageTargetSpecific"></option>
1743
</select>
1744
</div>
1745
<div class="col-md-8 d-none" id="admin-message-target-value-group">
1746
<label class="form-label" for="admin-message-target-value" data-loc="admin_messageTargetValue"></label>
1747
<input class="form-control" id="admin-message-target-value" />
1748
</div>
1749
</div>
1750
<div class="mb-2">
1751
<label class="form-label" for="admin-message-sender" data-loc="admin_messageSender"></label>
1752
<input class="form-control" id="admin-message-sender" value="/Lotus/Language/Bosses/Ordis" />
1753
</div>
1754
<div class="mb-2">
1755
<label class="form-label" for="admin-message-subject" data-loc="admin_messageSubject"></label>
1756
<input class="form-control" id="admin-message-subject" />
1757
</div>
1758
<div class="mb-2">
1759
<label class="form-label" for="admin-message-body" data-loc="admin_messageBody"></label>
1760
<textarea class="form-control" id="admin-message-body" rows="4"></textarea>
1761
</div>
1762
<div class="mb-2">
1763
<label class="form-label" for="admin-message-icon" data-loc="admin_messageIcon"></label>
1764
<input class="form-control" id="admin-message-icon" placeholder="/Lotus/Interface/Icons/Npcs/Ordis.png" />
1765
</div>
1766
<div class="mb-2">
1767
<label class="form-label" for="admin-message-att" data-loc="admin_messageAtt"></label>
1768
<textarea class="form-control" id="admin-message-att" rows="3" placeholder="/Lotus/Powersuits/Excalibur/ExcaliburPrime /Lotus/Weapons/Tenno/Melee/LongSword/SkanaPrime /Lotus/Weapons/Tenno/Pistol/LatoPrime"></textarea>
1769
</div>
1770
<div class="mb-2">
1771
<label class="form-label" for="admin-message-counted-att" data-loc="admin_messageCountedAtt"></label>
1772
<textarea class="form-control" id="admin-message-counted-att" rows="5" placeholder="[ { "ItemType": "/Lotus/Types/Items/MiscItems/OxiumAlloy", "ItemCount": 1200 }, { "ItemType": "/Lotus/Types/Items/MiscItems/OxiumAlloy", "ItemCount": 1200 } ]"></textarea>
1773
</div>
1774
<div class="form-check mb-3">
1775
<input class="form-check-input" type="checkbox" id="admin-message-high-priority" checked />
1776
<label class="form-check-label" for="admin-message-high-priority"><abbr data-loc="admin_messageHighPriority" data-loc-title="admin_messageHighPriorityHelp"></abbr></label>
1777
</div>
1778
<button class="btn btn-primary" id="admin-broadcast-submit" onclick="doAdminBroadcastInbox();" data-loc="admin_sendInboxMessage"></button>
1779
</div>
1780
</div>
1734
1781
</div>
1735
1782
</div>
1736
1783
</div>
@@ -5666,6 +5666,7 @@ single.getRoute("/webui/admin").on("beforeload", function () {
5666
5666
window.is_admin = true;
5667
5667
$(".admin-hide").addClass("d-none");
5668
5668
$(".admin-show").removeClass("d-none");
5669
onAdminMessageTargetModeChange();
5669
5670
document.getElementById("registered-losers").innerHTML = "";
5670
5671
for (const user of users) {
5671
5672
const tr = document.createElement("tr");
@@ -5716,3 +5717,138 @@ single.getRoute("/webui/admin").on("beforeload", function () {
5716
5717
});
5717
5718
});
5718
5719
});
5720
5721
function onAdminMessageTargetModeChange() {
5722
const targetMode = document.getElementById("admin-message-target-mode").value;
5723
document.getElementById("admin-message-target-value-group").classList.toggle("d-none", targetMode !== "specific");
5724
}
5725
5726
function resolveAdminBroadcastTargets(users, targetMode, targetValue) {
5727
if (targetMode === "all") {
5728
return users;
5729
}
5730
const normalizedTargetValue = targetValue.toLowerCase();
5731
const idMatches = users.filter(user => user.id === targetValue);
5732
return idMatches.length > 0
5733
? idMatches
5734
: users.filter(user => user.DisplayName.toLowerCase() === normalizedTargetValue);
5735
}
5736
5737
function buildAdminBroadcastConfirmMessage(targetMode, targetUsers) {
5738
if (targetMode === "all") {
5739
return loc("admin_sendToAllConfirm");
5740
}
5741
if (targetUsers.length === 1) {
5742
return loc("admin_sendToSpecificConfirmOne")
5743
.replaceAll("|NAME|", targetUsers[0].DisplayName)
5744
.replaceAll("|ID|", targetUsers[0].id);
5745
}
5746
return loc("admin_sendToSpecificConfirmMany").replaceAll("|COUNT|", String(targetUsers.length));
5747
}
5748
5749
function buildAdminInboxPayload(user, fields) {
5750
const payload = [
5751
{
5752
ownerId: user.id,
5753
sndr: fields.sender,
5754
sub: fields.subject,
5755
msg: fields.body,
5756
highPriority: fields.highPriority
5757
}
5758
];
5759
if (fields.icon) {
5760
payload[0].icon = fields.icon;
5761
}
5762
if (fields.attachments.length > 0) {
5763
payload[0].att = fields.attachments;
5764
}
5765
if (fields.countedAttachments && fields.countedAttachments.length > 0) {
5766
payload[0].countedAtt = fields.countedAttachments;
5767
}
5768
return payload;
5769
}
5770
5771
async function sendAdminInboxMessage(payload) {
5772
await $.ajax({
5773
url: "/custom/createMessage?" + window.authz,
5774
method: "POST",
5775
contentType: "application/json",
5776
data: JSON.stringify(payload)
5777
});
5778
}
5779
5780
async function doAdminBroadcastInbox() {
5781
await revalidateAuthz();
5782
const targetMode = document.getElementById("admin-message-target-mode").value;
5783
const targetValue = document.getElementById("admin-message-target-value").value.trim();
5784
const sender = document.getElementById("admin-message-sender").value.trim();
5785
const subject = document.getElementById("admin-message-subject").value.trim();
5786
const body = document.getElementById("admin-message-body").value.trim();
5787
const icon = document.getElementById("admin-message-icon").value.trim();
5788
const attRaw = document.getElementById("admin-message-att").value;
5789
const countedAttRaw = document.getElementById("admin-message-counted-att").value.trim();
5790
const highPriority = document.getElementById("admin-message-high-priority").checked;
5791
const submitButton = document.getElementById("admin-broadcast-submit");
5792
5793
if (!sender || !subject || !body) {
5794
alert(loc("admin_messageRequiredFields"));
5795
return;
5796
}
5797
if (targetMode === "specific" && !targetValue) {
5798
alert(loc("admin_messageTargetRequired"));
5799
return;
5800
}
5801
5802
let countedAttachments;
5803
if (countedAttRaw) {
5804
try {
5805
countedAttachments = JSON.parse(countedAttRaw);
5806
} catch (_error) {
5807
alert(loc("admin_messageCountedAttInvalid"));
5808
return;
5809
}
5810
if (!Array.isArray(countedAttachments)) {
5811
alert(loc("admin_messageCountedAttInvalid"));
5812
return;
5813
}
5814
}
5815
5816
const attachments = attRaw
5817
.split("\n")
5818
.map(x => x.trim())
5819
.filter(x => x);
5820
5821
submitButton.disabled = true;
5822
try {
5823
const users = await $.get("/custom/getRegisteredLosers?" + window.authz);
5824
const targetUsers = resolveAdminBroadcastTargets(users, targetMode, targetValue);
5825
if (targetUsers.length === 0) {
5826
alert(loc("admin_messageTargetNotFound"));
5827
return;
5828
}
5829
5830
const confirmMsg = buildAdminBroadcastConfirmMessage(targetMode, targetUsers);
5831
if (!window.confirm(confirmMsg)) {
5832
return;
5833
}
5834
5835
const payloadFields = {
5836
sender,
5837
subject,
5838
body,
5839
highPriority,
5840
icon,
5841
attachments,
5842
countedAttachments
5843
};
5844
for (const user of targetUsers) {
5845
const payload = buildAdminInboxPayload(user, payloadFields);
5846
await sendAdminInboxMessage(payload);
5847
}
5848
toast(loc("admin_sendToAllSuccess").replaceAll("|COUNT|", targetUsers.length));
5849
} catch (_error) {
5850
alert(loc("settings_changeFailed"));
5851
} finally {
5852
submitButton.disabled = false;
5853
}
5854
}
@@ -545,6 +545,28 @@ dict = {
545
545
navbar_admin: `Admin`,
546
546
admin_users: `Benutzer`,
547
547
admin_possess: `Als Benutzer anmelden`,
548
admin_broadcastInbox: `[UNTRANSLATED] Broadcast Inbox Message`,
549
admin_messageTargetMode: `[UNTRANSLATED] Target`,
550
admin_messageTargetAll: `[UNTRANSLATED] All Users`,
551
admin_messageTargetSpecific: `[UNTRANSLATED] Specific User`,
552
admin_messageTargetValue: `[UNTRANSLATED] Username or Account ID`,
553
admin_messageSender: `[UNTRANSLATED] Sender`,
554
admin_messageSubject: `[UNTRANSLATED] Subject`,
555
admin_messageBody: `[UNTRANSLATED] Message`,
556
admin_messageIcon: `[UNTRANSLATED] Icon (optional)`,
557
admin_messageAtt: `[UNTRANSLATED] Attachments (optional, one item type per line)`,
558
admin_messageCountedAtt: `[UNTRANSLATED] Counted Attachments (optional JSON)`,
559
admin_messageHighPriority: `[UNTRANSLATED] High Priority`,
560
admin_messageHighPriorityHelp: `[UNTRANSLATED] High priority messages cause the inbox to open automatically.`,
561
admin_sendInboxMessage: `[UNTRANSLATED] Send Inbox Message`,
562
admin_sendToAllConfirm: `[UNTRANSLATED] Are you sure you want to send this inbox message to all users?`,
563
admin_sendToSpecificConfirmOne: `[UNTRANSLATED] Send this inbox message to "|NAME|" (|ID|)?`,
564
admin_sendToSpecificConfirmMany: `[UNTRANSLATED] Send this inbox message to |COUNT| matching accounts?`,
565
admin_sendToAllSuccess: `[UNTRANSLATED] Successfully sent inbox message to |COUNT| user(s).`,
566
admin_messageRequiredFields: `[UNTRANSLATED] Sender, subject, and message are required.`,
567
admin_messageCountedAttInvalid: `[UNTRANSLATED] Counted attachments must be valid JSON array.`,
568
admin_messageTargetRequired: `[UNTRANSLATED] Username or account id is required for Specific User.`,
569
admin_messageTargetNotFound: `[UNTRANSLATED] No user matched that username or account id.`,
548
570
549
571
AVATAR_ABILITY_DURATION: `Dauer`,
550
572
AVATAR_ABILITY_EFFICIENCY: `Effizienz`,
@@ -544,6 +544,28 @@ dict = {
544
544
navbar_admin: `Admin`,
545
545
admin_users: `Users`,
546
546
admin_possess: `Impersonate`,
547
admin_broadcastInbox: `Broadcast Inbox Message`,
548
admin_messageTargetMode: `Target`,
549
admin_messageTargetAll: `All Users`,
550
admin_messageTargetSpecific: `Specific User`,
551
admin_messageTargetValue: `Username or Account ID`,
552
admin_messageSender: `Sender`,
553
admin_messageSubject: `Subject`,
554
admin_messageBody: `Message`,
555
admin_messageIcon: `Icon (optional)`,
556
admin_messageAtt: `Attachments (optional, one item type per line)`,
557
admin_messageCountedAtt: `Counted Attachments (optional JSON)`,
558
admin_messageHighPriority: `High Priority`,
559
admin_messageHighPriorityHelp: `High priority messages cause the inbox to open automatically.`,
560
admin_sendInboxMessage: `Send Inbox Message`,
561
admin_sendToAllConfirm: `Are you sure you want to send this inbox message to all users?`,
562
admin_sendToSpecificConfirmOne: `Send this inbox message to "|NAME|" (|ID|)?`,
563
admin_sendToSpecificConfirmMany: `Send this inbox message to |COUNT| matching accounts?`,
564
admin_sendToAllSuccess: `Successfully sent inbox message to |COUNT| user(s).`,
565
admin_messageRequiredFields: `Sender, subject, and message are required.`,
566
admin_messageCountedAttInvalid: `Counted attachments must be valid JSON array.`,
567
admin_messageTargetRequired: `Username or account id is required for Specific User.`,
568
admin_messageTargetNotFound: `No user matched that username or account id.`,
547
569
548
570
AVATAR_ABILITY_DURATION: `Duration`,
549
571
AVATAR_ABILITY_EFFICIENCY: `Efficiency`,
@@ -545,6 +545,28 @@ dict = {
545
545
navbar_admin: `[UNTRANSLATED] Admin`,
546
546
admin_users: `[UNTRANSLATED] Users`,
547
547
admin_possess: `[UNTRANSLATED] Impersonate`,
548
admin_broadcastInbox: `[UNTRANSLATED] Broadcast Inbox Message`,
549
admin_messageTargetMode: `[UNTRANSLATED] Target`,
550
admin_messageTargetAll: `[UNTRANSLATED] All Users`,
551
admin_messageTargetSpecific: `[UNTRANSLATED] Specific User`,
552
admin_messageTargetValue: `[UNTRANSLATED] Username or Account ID`,
553
admin_messageSender: `[UNTRANSLATED] Sender`,
554
admin_messageSubject: `[UNTRANSLATED] Subject`,
555
admin_messageBody: `[UNTRANSLATED] Message`,
556
admin_messageIcon: `[UNTRANSLATED] Icon (optional)`,
557
admin_messageAtt: `[UNTRANSLATED] Attachments (optional, one item type per line)`,
558
admin_messageCountedAtt: `[UNTRANSLATED] Counted Attachments (optional JSON)`,
559
admin_messageHighPriority: `[UNTRANSLATED] High Priority`,
560
admin_messageHighPriorityHelp: `[UNTRANSLATED] High priority messages cause the inbox to open automatically.`,
561
admin_sendInboxMessage: `[UNTRANSLATED] Send Inbox Message`,
562
admin_sendToAllConfirm: `[UNTRANSLATED] Are you sure you want to send this inbox message to all users?`,
563
admin_sendToSpecificConfirmOne: `[UNTRANSLATED] Send this inbox message to "|NAME|" (|ID|)?`,
564
admin_sendToSpecificConfirmMany: `[UNTRANSLATED] Send this inbox message to |COUNT| matching accounts?`,
565
admin_sendToAllSuccess: `[UNTRANSLATED] Successfully sent inbox message to |COUNT| user(s).`,
566
admin_messageRequiredFields: `[UNTRANSLATED] Sender, subject, and message are required.`,
567
admin_messageCountedAttInvalid: `[UNTRANSLATED] Counted attachments must be valid JSON array.`,
568
admin_messageTargetRequired: `[UNTRANSLATED] Username or account id is required for Specific User.`,
569
admin_messageTargetNotFound: `[UNTRANSLATED] No user matched that username or account id.`,
548
570
549
571
AVATAR_ABILITY_DURATION: `Duración`,
550
572
AVATAR_ABILITY_EFFICIENCY: `Eficiencia`,
@@ -545,6 +545,28 @@ dict = {
545
545
navbar_admin: `Administrateur`,
546
546
admin_users: `Utilisateurs`,
547
547
admin_possess: `[UNTRANSLATED] Impersonate`,
548
admin_broadcastInbox: `[UNTRANSLATED] Broadcast Inbox Message`,
549
admin_messageTargetMode: `[UNTRANSLATED] Target`,
550
admin_messageTargetAll: `[UNTRANSLATED] All Users`,
551
admin_messageTargetSpecific: `[UNTRANSLATED] Specific User`,
552
admin_messageTargetValue: `[UNTRANSLATED] Username or Account ID`,
553
admin_messageSender: `[UNTRANSLATED] Sender`,
554
admin_messageSubject: `[UNTRANSLATED] Subject`,
555
admin_messageBody: `[UNTRANSLATED] Message`,
556
admin_messageIcon: `[UNTRANSLATED] Icon (optional)`,
557
admin_messageAtt: `[UNTRANSLATED] Attachments (optional, one item type per line)`,
558
admin_messageCountedAtt: `[UNTRANSLATED] Counted Attachments (optional JSON)`,
559
admin_messageHighPriority: `[UNTRANSLATED] High Priority`,
560
admin_messageHighPriorityHelp: `[UNTRANSLATED] High priority messages cause the inbox to open automatically.`,
561
admin_sendInboxMessage: `[UNTRANSLATED] Send Inbox Message`,
562
admin_sendToAllConfirm: `[UNTRANSLATED] Are you sure you want to send this inbox message to all users?`,
563
admin_sendToSpecificConfirmOne: `[UNTRANSLATED] Send this inbox message to "|NAME|" (|ID|)?`,
564
admin_sendToSpecificConfirmMany: `[UNTRANSLATED] Send this inbox message to |COUNT| matching accounts?`,
565
admin_sendToAllSuccess: `[UNTRANSLATED] Successfully sent inbox message to |COUNT| user(s).`,
566
admin_messageRequiredFields: `[UNTRANSLATED] Sender, subject, and message are required.`,
567
admin_messageCountedAttInvalid: `[UNTRANSLATED] Counted attachments must be valid JSON array.`,
568
admin_messageTargetRequired: `[UNTRANSLATED] Username or account id is required for Specific User.`,
569
admin_messageTargetNotFound: `[UNTRANSLATED] No user matched that username or account id.`,
548
570
549
571
AVATAR_ABILITY_DURATION: `Durée`,
550
572
AVATAR_ABILITY_EFFICIENCY: `Efficacité`,
@@ -545,6 +545,28 @@ dict = {
545
545
navbar_admin: `Админ`,
546
546
admin_users: `Пользователи`,
547
547
admin_possess: `Дейстовать от имени`,
548
admin_broadcastInbox: `[UNTRANSLATED] Broadcast Inbox Message`,
549
admin_messageTargetMode: `[UNTRANSLATED] Target`,
550
admin_messageTargetAll: `[UNTRANSLATED] All Users`,
551
admin_messageTargetSpecific: `[UNTRANSLATED] Specific User`,
552
admin_messageTargetValue: `[UNTRANSLATED] Username or Account ID`,
553
admin_messageSender: `[UNTRANSLATED] Sender`,
554
admin_messageSubject: `[UNTRANSLATED] Subject`,
555
admin_messageBody: `[UNTRANSLATED] Message`,
556
admin_messageIcon: `[UNTRANSLATED] Icon (optional)`,
557
admin_messageAtt: `[UNTRANSLATED] Attachments (optional, one item type per line)`,
558
admin_messageCountedAtt: `[UNTRANSLATED] Counted Attachments (optional JSON)`,
559
admin_messageHighPriority: `[UNTRANSLATED] High Priority`,
560
admin_messageHighPriorityHelp: `[UNTRANSLATED] High priority messages cause the inbox to open automatically.`,
561
admin_sendInboxMessage: `[UNTRANSLATED] Send Inbox Message`,
562
admin_sendToAllConfirm: `[UNTRANSLATED] Are you sure you want to send this inbox message to all users?`,
563
admin_sendToSpecificConfirmOne: `[UNTRANSLATED] Send this inbox message to "|NAME|" (|ID|)?`,
564
admin_sendToSpecificConfirmMany: `[UNTRANSLATED] Send this inbox message to |COUNT| matching accounts?`,
565
admin_sendToAllSuccess: `[UNTRANSLATED] Successfully sent inbox message to |COUNT| user(s).`,
566
admin_messageRequiredFields: `[UNTRANSLATED] Sender, subject, and message are required.`,
567
admin_messageCountedAttInvalid: `[UNTRANSLATED] Counted attachments must be valid JSON array.`,
568
admin_messageTargetRequired: `[UNTRANSLATED] Username or account id is required for Specific User.`,
569
admin_messageTargetNotFound: `[UNTRANSLATED] No user matched that username or account id.`,
548
570
549
571
AVATAR_ABILITY_DURATION: `Длительность`,
550
572
AVATAR_ABILITY_EFFICIENCY: `Эффективность`,
@@ -545,6 +545,28 @@ dict = {
545
545
navbar_admin: `[UNTRANSLATED] Admin`,
546
546
admin_users: `[UNTRANSLATED] Users`,
547
547
admin_possess: `[UNTRANSLATED] Impersonate`,
548
admin_broadcastInbox: `[UNTRANSLATED] Broadcast Inbox Message`,
549
admin_messageTargetMode: `[UNTRANSLATED] Target`,
550
admin_messageTargetAll: `[UNTRANSLATED] All Users`,
551
admin_messageTargetSpecific: `[UNTRANSLATED] Specific User`,
552
admin_messageTargetValue: `[UNTRANSLATED] Username or Account ID`,
553
admin_messageSender: `[UNTRANSLATED] Sender`,
554
admin_messageSubject: `[UNTRANSLATED] Subject`,
555
admin_messageBody: `[UNTRANSLATED] Message`,
556
admin_messageIcon: `[UNTRANSLATED] Icon (optional)`,
557
admin_messageAtt: `[UNTRANSLATED] Attachments (optional, one item type per line)`,
558
admin_messageCountedAtt: `[UNTRANSLATED] Counted Attachments (optional JSON)`,
559
admin_messageHighPriority: `[UNTRANSLATED] High Priority`,
560
admin_messageHighPriorityHelp: `[UNTRANSLATED] High priority messages cause the inbox to open automatically.`,
561
admin_sendInboxMessage: `[UNTRANSLATED] Send Inbox Message`,
562
admin_sendToAllConfirm: `[UNTRANSLATED] Are you sure you want to send this inbox message to all users?`,
563
admin_sendToSpecificConfirmOne: `[UNTRANSLATED] Send this inbox message to "|NAME|" (|ID|)?`,
564
admin_sendToSpecificConfirmMany: `[UNTRANSLATED] Send this inbox message to |COUNT| matching accounts?`,
565
admin_sendToAllSuccess: `[UNTRANSLATED] Successfully sent inbox message to |COUNT| user(s).`,
566
admin_messageRequiredFields: `[UNTRANSLATED] Sender, subject, and message are required.`,
567
admin_messageCountedAttInvalid: `[UNTRANSLATED] Counted attachments must be valid JSON array.`,
568
admin_messageTargetRequired: `[UNTRANSLATED] Username or account id is required for Specific User.`,
569
admin_messageTargetNotFound: `[UNTRANSLATED] No user matched that username or account id.`,
548
570
549
571
AVATAR_ABILITY_DURATION: `Тривалість`,
550
572
AVATAR_ABILITY_EFFICIENCY: `Ощадливість`,
@@ -545,6 +545,28 @@ dict = {
545
545
navbar_admin: `管理员`,
546
546
admin_users: `用户`,
547
547
admin_possess: `管理此账户`,
548
admin_broadcastInbox: `[UNTRANSLATED] Broadcast Inbox Message`,
549
admin_messageTargetMode: `[UNTRANSLATED] Target`,
550
admin_messageTargetAll: `[UNTRANSLATED] All Users`,
551
admin_messageTargetSpecific: `[UNTRANSLATED] Specific User`,
552
admin_messageTargetValue: `[UNTRANSLATED] Username or Account ID`,
553
admin_messageSender: `[UNTRANSLATED] Sender`,
554
admin_messageSubject: `[UNTRANSLATED] Subject`,
555
admin_messageBody: `[UNTRANSLATED] Message`,
556
admin_messageIcon: `[UNTRANSLATED] Icon (optional)`,
557
admin_messageAtt: `[UNTRANSLATED] Attachments (optional, one item type per line)`,
558
admin_messageCountedAtt: `[UNTRANSLATED] Counted Attachments (optional JSON)`,
559
admin_messageHighPriority: `[UNTRANSLATED] High Priority`,
560
admin_messageHighPriorityHelp: `[UNTRANSLATED] High priority messages cause the inbox to open automatically.`,
561
admin_sendInboxMessage: `[UNTRANSLATED] Send Inbox Message`,
562
admin_sendToAllConfirm: `[UNTRANSLATED] Are you sure you want to send this inbox message to all users?`,
563
admin_sendToSpecificConfirmOne: `[UNTRANSLATED] Send this inbox message to "|NAME|" (|ID|)?`,
564
admin_sendToSpecificConfirmMany: `[UNTRANSLATED] Send this inbox message to |COUNT| matching accounts?`,
565
admin_sendToAllSuccess: `[UNTRANSLATED] Successfully sent inbox message to |COUNT| user(s).`,
566
admin_messageRequiredFields: `[UNTRANSLATED] Sender, subject, and message are required.`,
567
admin_messageCountedAttInvalid: `[UNTRANSLATED] Counted attachments must be valid JSON array.`,
568
admin_messageTargetRequired: `[UNTRANSLATED] Username or account id is required for Specific User.`,
569
admin_messageTargetNotFound: `[UNTRANSLATED] No user matched that username or account id.`,
548
570
549
571
AVATAR_ABILITY_DURATION: `持续时间`,
550
572
AVATAR_ABILITY_EFFICIENCY: `效率`,