diff --git a/chat.js b/chat.js index 129b4524..afb41d49 100644 --- a/chat.js +++ b/chat.js @@ -456,7 +456,9 @@ function updateGameChatMessageVisibility() { } } -function chatInputActionFired() { +async function chatInputActionFired() { + if (!await ensurePlayerConfirmedChatAgeWarning()) return; + const chatInput = document.getElementById("chatInput"); if (!chatInput?.value.trim().length) return; @@ -563,7 +565,7 @@ function initChat() { document.getSelection().collapseToEnd(); }; gameChatInput.onblur = () => gameChatContainer.classList.remove('focused'); - gameChatInput.onkeydown = function (e) { + gameChatInput.onkeydown = async function (e) { if (e.key === 'Tab') { e.preventDefault(); cycleGameChatMode(); @@ -576,6 +578,7 @@ function initChat() { e.preventDefault(); if (!playerName) return; + if (!await ensurePlayerConfirmedChatAgeWarning()) return; switch (gameChatModeIndex) { case 0: if (!trySendMapMessage(chatMessageContent)) @@ -654,6 +657,18 @@ function trySendGlobalMessage(content) { return false; } +async function ensurePlayerConfirmedChatAgeWarning() { + if (globalConfig.chatAgeWarningConfirmed) return true; + + return new Promise(resolve => { + showConfirmLikeModal('chatAgeWarningModal', () => { + resolve(true); + globalConfig.chatAgeWarningConfirmed = true; + updateConfig(globalConfig, true); + }, () => resolve(false)); + }) +} + function addChatTip() { const tips = localizedMessages.chatTips.tips; if (++globalConfig.chatTipIndex >= Object.keys(tips).length) diff --git a/index.php b/index.php index e37bc727..fce75fcd 100644 --- a/index.php +++ b/index.php @@ -1755,6 +1755,7 @@ class="joystickBase" />

Report

+

Please create reports responsibly. Repeated frivolous reports will be penalized.

+
- - + +
diff --git a/lang/ar.json b/lang/ar.json index fea22ba3..11d1e8b7 100644 --- a/lang/ar.json +++ b/lang/ar.json @@ -574,7 +574,8 @@ "placeholder": "Custom reason (max 50 characters)", "other": "Other (specify)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "القواعد", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/de.json b/lang/de.json index 93007fd6..0e8c88a3 100644 --- a/lang/de.json +++ b/lang/de.json @@ -574,7 +574,8 @@ "placeholder": "Sonstiger Grund (maximal 50 Zeichen)", "other": "Sonstiges (begründen)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Regeln", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/en.json b/lang/en.json index 844ef686..87e28083 100644 --- a/lang/en.json +++ b/lang/en.json @@ -560,6 +560,7 @@ }, "report": { "title": "Report", + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized.", "submit": "Submit", "fields": { "reason": { @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/eo.json b/lang/eo.json index f8af9103..bdd021dd 100644 --- a/lang/eo.json +++ b/lang/eo.json @@ -574,7 +574,8 @@ "placeholder": "Custom reason (max 50 characters)", "other": "Other (specify)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Reguloj", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/es.json b/lang/es.json index 90b6c8a9..0716401d 100644 --- a/lang/es.json +++ b/lang/es.json @@ -574,7 +574,8 @@ "placeholder": "Razón Personalizada (máximo 50 caracteres)", "other": "Otra (especificar)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Reglas", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/fr.json b/lang/fr.json index e4b79a52..1398cf79 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -574,7 +574,8 @@ "placeholder": "Raison personnalisée (maximum 50 caractères)", "other": "Autre (spécifier)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Règles", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/id.json b/lang/id.json index ae38a9d4..cf4d5de8 100644 --- a/lang/id.json +++ b/lang/id.json @@ -574,7 +574,8 @@ "placeholder": "Custom reason (max 50 characters)", "other": "Other (specify)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Rules", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/it.json b/lang/it.json index 02a25409..f87bafcb 100644 --- a/lang/it.json +++ b/lang/it.json @@ -574,7 +574,8 @@ "placeholder": "Custom reason (max 50 characters)", "other": "Other (specify)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Regole", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/ja.json b/lang/ja.json index c62f05e8..9c67b9cd 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -574,7 +574,8 @@ "placeholder": "任意の理由を記入してください", "other": "その他 (任意記入)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "ルール", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { @@ -1251,4 +1260,4 @@ } } } -} +} \ No newline at end of file diff --git a/lang/ko.json b/lang/ko.json index 377ad629..a38690e1 100644 --- a/lang/ko.json +++ b/lang/ko.json @@ -574,7 +574,8 @@ "placeholder": "50자 한도 내로 상세히 서술하여 주십시오.", "other": "기타 (직접 작성)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "규칙", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/pl.json b/lang/pl.json index bd380982..f40d596a 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -574,7 +574,8 @@ "placeholder": "Custom reason (max 50 characters)", "other": "Other (specify)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Zasady", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/pt.json b/lang/pt.json index 97f07a45..28ae509a 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -574,7 +574,8 @@ "placeholder": "Motivo customizado (maximo de 50 Caracteres, em inglês)", "other": "Outro (especifique)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Regras", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/ro.json b/lang/ro.json index f157c6b1..5fde7651 100644 --- a/lang/ro.json +++ b/lang/ro.json @@ -574,7 +574,8 @@ "placeholder": "Motiv personalizat (max 50 caractere)", "other": "Altul (specifică)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Reguli", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/ru.json b/lang/ru.json index 363342b0..cf2ff597 100644 --- a/lang/ru.json +++ b/lang/ru.json @@ -574,7 +574,8 @@ "placeholder": "Своя причина (до 50 символов)", "other": "Другое (укажите)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Правила", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { @@ -1251,4 +1260,4 @@ } } } -} +} \ No newline at end of file diff --git a/lang/tr.json b/lang/tr.json index f96fd7ab..05ffb20c 100644 --- a/lang/tr.json +++ b/lang/tr.json @@ -574,7 +574,8 @@ "placeholder": "Özel Sebep (en fazla 50 karakter)", "other": "Başka (detaylandırın)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Kurallar", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/uk.json b/lang/uk.json index 11e08e90..aa977a96 100644 --- a/lang/uk.json +++ b/lang/uk.json @@ -574,7 +574,8 @@ "placeholder": "Інша причина (макс. 50 символів)", "other": "Інше (вкажіть причину)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Правила", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/vi.json b/lang/vi.json index 9d21ed08..1c8984c1 100644 --- a/lang/vi.json +++ b/lang/vi.json @@ -574,7 +574,8 @@ "placeholder": "Lý do khác (tối đa 50 ký tự)", "other": "Khác (nêu rõ)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "Nội quy", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/zh.json b/lang/zh.json index bd054dc5..cc377d1d 100644 --- a/lang/zh.json +++ b/lang/zh.json @@ -574,7 +574,8 @@ "placeholder": "自定义原因(最多50个字符)", "other": "其他(请注明)" } - } + }, + "subtitle": "Please create reports responsibly. Repeated frivolous reports will be penalized." }, "rules": { "title": "多人游戏守则", @@ -619,6 +620,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/play.css b/play.css index 97eb07aa..337a0875 100644 --- a/play.css +++ b/play.css @@ -345,7 +345,7 @@ body { flex-wrap: wrap; } -.uiControl { +.uiControl, .chatRulesInfo { text-align: center; } diff --git a/play.js b/play.js index 4a7a7fae..190e4e7f 100644 --- a/play.js +++ b/play.js @@ -55,6 +55,8 @@ let gameMapHandle = new WeakRef({}); const modalTransitionDuration = 230; +const confirmLikeModals = ['confirmModal', 'chatAgeWarningModal']; + const langLabelMassageFunctions = { 'ja': (value, isUI) => { if (typeof value === 'string' && /<[^>]+>/.test(value)) { @@ -96,6 +98,7 @@ let globalConfig = { questionablePreloads: false, rulesReviewed: false, warningsReviewed: false, + chatAgeWarningConfirmed: false, badgeToolsData: null, pushNotificationToastDismissed: false, unicodeFont: false, @@ -782,7 +785,8 @@ function closeModal() { updateFullscreenPolling(); } - setModalUiTheme('confirmModal', config.uiTheme === 'auto' ? systemName : config.uiTheme); + for (const modal of confirmLikeModals) + setModalUiTheme(modal, config.uiTheme === 'auto' ? systemName : config.uiTheme); if (modalContainer.dataset.lastModalId) { const lastModalIdSeparatorIndex = modalContainer.dataset.lastModalId.lastIndexOf(','); @@ -804,8 +808,6 @@ function closeModal() { } function showConfirmModal(message, okCallback, cancelCallback) { - const modalContainer = document.getElementById('confirmModalContainer'); - const modal = document.getElementById('confirmModal'); if (!modal.classList.contains('hidden')) { @@ -813,13 +815,39 @@ function showConfirmModal(message, okCallback, cancelCallback) { return; } + modal.querySelector('.confirmMessage').innerHTML = getMassagedLabel(message, true); + showConfirmLikeModal('confirmModal', okCallback, cancelCallback); +} + +function showConfirmLikeModal(modalId, okCallback, cancelCallback) { + const modal = document.getElementById(modalId); + if (!modal.classList.contains('hidden')) { + setTimeout(() => showConfirmLikeModal(modalId, okCallback, cancelCallback), modalTransitionDuration); + return; + } + + const modalContainer = modal.parentElement; + + function closeConfirmModal(callback) { + modalContainer.classList.add('fadeOut'); + modal.classList.add('fadeOut'); + + setTimeout(() => { + modal.classList.add('hidden'); + modal.classList.remove('fadeOut'); + modalContainer.classList.add('hidden'); + modalContainer.classList.remove('fadeOut'); + }, modalTransitionDuration); + + if (callback) + callback(); + } + modalContainer.classList.remove('fadeOut', 'hidden'); modalContainer.classList.add('fadeIn'); - modal.querySelector('.confirmMessage').innerHTML = getMassagedLabel(message, true); - - modal.querySelector('.confirmOkButton').onclick = () => closeConfirmModal(okCallback); - modal.querySelector('.confirmCancelButton').onclick = () => closeConfirmModal(cancelCallback); + modal.querySelector('.jsConfirm').onclick = () => closeConfirmModal(okCallback); + modal.querySelector('.jsCancel').onclick = () => closeConfirmModal(cancelCallback); modal.classList.add('fadeIn'); modal.classList.remove('hidden'); @@ -833,29 +861,12 @@ function showConfirmModal(message, okCallback, cancelCallback) { }, modalTransitionDuration); } -function closeConfirmModal(callback) { - const modalContainer = document.getElementById('confirmModalContainer'); - const modal = document.getElementById('confirmModal'); - - modalContainer.classList.add('fadeOut'); - modal.classList.add('fadeOut'); - - setTimeout(() => { - modal.classList.add('hidden'); - modal.classList.remove('fadeOut'); - modalContainer.classList.add('hidden'); - modalContainer.classList.remove('fadeOut'); - }, modalTransitionDuration); - - if (callback) - callback(); -} - document.getElementById('enterNameForm').onsubmit = function () { setName(document.getElementById('nameInput').value); }; { + /** @this {HTMLInputElement} */ function oninputYnomoji() { const ynomojiPattern = /:([a-z0-9_\-]+(?::|$)|$)/gi; const ynomojiContainer = document.getElementById('ynomojiContainer');