Skip to content

Commit

Permalink
🪲 Change TWElements select to our owns (hedyorg#5438)
Browse files Browse the repository at this point in the history
The current dropdowns are part of a paid library and therefore are very hard to target in JS. Replace them with Hasan's select to  be able to have control over them.

Fixes hedyorg#5290


**How to test**

Customizing an adventure should work normally
  • Loading branch information
jpelay authored May 6, 2024
1 parent c7fbde9 commit d72086a
Show file tree
Hide file tree
Showing 68 changed files with 858 additions and 964 deletions.
3 changes: 2 additions & 1 deletion build-tools/heroku/generate-client-messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
'directly_available',
'disabled',
'adventures_restored',
'multiple_keywords_warning'
'multiple_keywords_warning',
'selected'
]


Expand Down
2 changes: 1 addition & 1 deletion build-tools/heroku/tailwind/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ code {
}

.dropdown-menu {
@apply absolute overflow-hidden block rounded-md ltr:right-0 rtl:left-0 ltr:mr-1 rtl:ml-1 w-max p-4 shadow-lg;;
@apply absolute block rounded-md ltr:right-0 rtl:left-0 ltr:mr-1 rtl:ml-1 w-max p-4 shadow-lg;;
top: 40px;
@apply cursor-auto; /* Undo cursor-pointer we inherit from the menu */
}
Expand Down
3 changes: 2 additions & 1 deletion content/client-messages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ gettext('customization_deleted')
gettext('directly_available')
gettext('disabled')
gettext('adventures_restored')
gettext('multiple_keywords_warning')
gettext('multiple_keywords_warning')
gettext('selected')
9 changes: 6 additions & 3 deletions messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2000-01-01 00:00+0000\n"
"PO-Revision-Date: 2000-01-01 00:00+0000\n"
"Last-Translator: Someone <[email protected]>\n"
"POT-Creation-Date: 2024-04-22 12:26-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
Expand Down Expand Up @@ -1019,6 +1019,9 @@ msgstr ""
msgid "multiple_keywords_warning"
msgstr ""

msgid "multiple_levels_warning"
msgstr ""

msgid "my_account"
msgstr ""

Expand Down
6 changes: 0 additions & 6 deletions static/css/generated.full.css
Original file line number Diff line number Diff line change
Expand Up @@ -30285,11 +30285,6 @@ code {
border-color: rgb(220 76 100 / var(--tw-border-opacity)) !important;
}

.\!border-gray-200 {
--tw-border-opacity: 1 !important;
border-color: rgb(237 242 247 / var(--tw-border-opacity)) !important;
}

.\!border-gray-400 {
--tw-border-opacity: 1 !important;
border-color: rgb(203 213 224 / var(--tw-border-opacity)) !important;
Expand Down Expand Up @@ -343964,7 +343959,6 @@ code {
display: block;
width: -moz-max-content;
width: max-content;
overflow: hidden;
border-radius: 0.375rem;
padding: 1rem;
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
Expand Down
66 changes: 20 additions & 46 deletions static/js/adventure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,49 +21,44 @@ let keywordHasAlert: Map<string, boolean> = new Map()
export async function initializeCustomAdventurePage(_options: InitializeCustomizeAdventurePage) {
const editorContainer = document.querySelector('#adventure-editor') as HTMLElement;
// Initialize the editor with the default language
let lang = $('#language').val() as string || 'en'
let lang = document.querySelector('#languages_dropdown> .option.selected')!.getAttribute('data-value') as string
const TRADUCTIONS = convert(TRADUCTION_IMPORT) as Map<string, Map<string,string>>;
if (!TRADUCTIONS.has(lang)) { lang = 'en'; }
let TRADUCTION = TRADUCTIONS.get(lang) as Map<string,string>;

if (editorContainer) {
await initializeEditor(lang, editorContainer);
showWarningIfMultipleLevels(TRADUCTION)
$editor.model.document.on('change:data', () => {
showWarningIfMultipleLevels(TRADUCTION)
showWarningIfMultipleKeywords(TRADUCTION)
$editor.model.document.on('change:data', () => {
showWarningIfMultipleKeywords(TRADUCTION)
})
}

$('#language').on('change', () => {
let lang = $('#language').val() as string || 'en'
let lang = document.querySelector('#languages_dropdown> .option.selected')!.getAttribute('data-value') as string
if (!TRADUCTIONS.has(lang)) { lang = 'en'; }
TRADUCTION = TRADUCTIONS.get(lang) as Map<string,string>;
})
// Autosave customize adventure page
autoSave("customize_adventure")

// We wait until Tailwind generates the select
const tailwindSelects = await waitForElm('[data-te-select-option-ref]')
tailwindSelects.forEach((el) => {

showWarningIfMultipleLevels()
document.querySelectorAll('#levels_dropdown > .option').forEach((el) => {
el.addEventListener('click', () => {
// After clicking, it takes some time for the checkbox to change state, so if we want to target the checkboxess
// that are checked after clicking we can't do that inmediately after the click
// therofore we wait for 100ms
setTimeout(function(){
const numberOfLevels = document.querySelectorAll('[aria-selected="true"]').length;
const numberOfSnippets = document.querySelectorAll('pre[data-language="Hedy"]').length
if(numberOfLevels > 1 && numberOfSnippets > 0) {
$('#warningbox').show()
} else if(numberOfLevels <= 1 || numberOfSnippets === 0) {
$('#warningbox').hide()
}
}, 100);
setTimeout(showWarningIfMultipleLevels, 100)
})
})

}

function showWarningIfMultipleLevels(TRADUCTION: Map<string, string>) {
function showWarningIfMultipleLevels() {
const numberOfLevels = document.querySelectorAll('#levels_dropdown > .option.selected').length;
const numberOfSnippets = document.querySelectorAll('pre[data-language="Hedy"]').length
if(numberOfLevels > 1 && numberOfSnippets > 0) {
$('#warningbox').show()
} else if(numberOfLevels <= 1 || numberOfSnippets === 0) {
$('#warningbox').hide()
}
}
function showWarningIfMultipleKeywords(TRADUCTION: Map<string, string>) {
const content = DOMPurify.sanitize($editor.getData())
const parser = new DOMParser();
const html = parser.parseFromString(content, 'text/html');
Expand Down Expand Up @@ -210,7 +205,7 @@ export function addCurlyBracesToCode(code: string, level: number, language: stri
}

export function addCurlyBracesToKeyword(name: string) {
let lang = $('#language').val() as string || 'en'
let lang = document.querySelector('#languages_dropdown> .option.selected')!.getAttribute('data-value') as string
const TRADUCTIONS = convert(TRADUCTION_IMPORT) as Map<string, Map<string,string>>;
if (!TRADUCTIONS.has(lang)) { lang = 'en'; }
let TRADUCTION = TRADUCTIONS.get(lang) as Map<string,string>;
Expand All @@ -222,25 +217,4 @@ export function addCurlyBracesToKeyword(name: string) {
}

return name;
}

function waitForElm(selector: string): Promise<NodeListOf<Element>> {
return new Promise(resolve => {
if (document.querySelector(selector)) {
return resolve(document.querySelectorAll(selector));
}

const observer = new MutationObserver(_mutations => {
if (document.querySelector(selector)) {
observer.disconnect();
resolve(document.querySelectorAll(selector));
}
});

// If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336
observer.observe(document.body, {
childList: true,
subtree: true
});
});
}
Loading

0 comments on commit d72086a

Please sign in to comment.