') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Implement per player locale (Implements #2029) by Phoenix616 · Pull Request #2502 · EssentialsX/Essentials · GitHub
Skip to content

Implement per player locale (Implements #2029) - #2502

Closed
Phoenix616 wants to merge 1 commit into
EssentialsX:2.xfrom
HypariaMC:2.x-upstream-per-player-locale
Closed

Implement per player locale (Implements #2029)#2502
Phoenix616 wants to merge 1 commit into
EssentialsX:2.xfrom
HypariaMC:2.x-upstream-per-player-locale

Conversation

@Phoenix616

@Phoenix616Phoenix616 commented Apr 23, 2019

Copy link
Copy Markdown
Contributor

This implements a per-player locale system like requested in #2029 which uses the client's language setting by default and adds a command to allow players to change their own locale on the server without changing the client language. The original locale config setting now acts as the default language when no locale is available for the player's locale or, if change-locale is disabled in the config behaves exactly like before using the same locale for all players (should be default with an old config).

This change goes along with moving all translations that get send from the static I18n.tl method to one provided by the User/CommandSource to get translations depending on the selected locale and also a convenience method sendTl to directly send translations.

Edit: Forgot to mention it: This also includes a provider for getting the client's locale on older versions that didn't include the locale API to keep this functionality backwards compatible.

Closes#2029

@mdcfe

Copy link
Copy Markdown
Member

Thanks for the PR!

However, due to incoming changes to how messaging works (#2391) in 2.18.x and our current schedule, this likely will not be merged into 2.x until after 2.17.0.

@Phoenix616

Copy link
Copy Markdown
ContributorAuthor

Is there any place where the schedule is laid out? Or is that just an internal thing?

Also this might be a good base for some of the ideas laid out regarding messaging changes, especially for the PlaceholderAPI support as it switches the messaging system from a global translator to a per-user translator which could the handle the PlaceholderAPI integration.

@mdcfe

mdcfe commented Apr 23, 2019

Copy link
Copy Markdown
Member

You can see loosely what the plans are for versions at the milestones.

This PR could definitely serve as a base to build on for any changes in #2391.

@mdcfemdcfe added the type: enhancement Features and feature requests. label Apr 23, 2019
@mdcfemdcfe self-assigned this Apr 23, 2019
@mdcfemdcfe added this to the 2.18.0 milestone Apr 23, 2019
@mdcfemdcfe mentioned this pull request Apr 19, 2020
6 tasks
@darbyjackdarbyjack modified the milestones: 2.18.0, 3.0May 13, 2020
@SladeHazardSladeHazard mentioned this pull request Nov 21, 2020
@ChewChew added the status: needs manual rebase Needs a manual local rebase due to base changes (regardless of what GH says) label Nov 25, 2020
@pop4959pop4959 mentioned this pull request Dec 27, 2020
@JRoy

JRoy commented Jan 12, 2022

Copy link
Copy Markdown
Member

Closed in favor of #4717

@JRoyJRoy closed this Jan 12, 2022
@TheKrafterTheKrafter mentioned this pull request Nov 24, 2023
4 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: needs manual rebaseNeeds a manual local rebase due to base changes (regardless of what GH says)type: enhancementFeatures and feature requests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Essentials localization based on player client language

5 participants

@Phoenix616@mdcfe@JRoy@Chew@darbyjack