diff --git a/code/modules/language/_language_menu.dm b/code/modules/language/_language_menu.dm index 905be8169e2..487c0e67be1 100644 --- a/code/modules/language/_language_menu.dm +++ b/code/modules/language/_language_menu.dm @@ -12,6 +12,9 @@ return GLOB.language_menu_state /datum/language_menu/ui_interact(mob/user, datum/tgui/ui) + if(isnull(language_holder.selected_language)) + language_holder.get_selected_language() + ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "LanguageMenu") @@ -21,38 +24,26 @@ var/list/data = list() var/atom/movable/speaker = language_holder.owner - data["is_living"] = isliving(speaker) data["languages"] = list() for(var/datum/language/language as anything in GLOB.all_languages) - var/result = language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE) - if(!result) - continue var/list/lang_data = list() lang_data["name"] = initial(language.name) lang_data["desc"] = initial(language.desc) lang_data["key"] = initial(language.key) lang_data["is_default"] = (language == language_holder.selected_language) + lang_data["icon"] = initial(language.icon) + lang_data["icon_state"] = initial(language.icon_state) if(speaker) - lang_data["can_speak"] = speaker.can_speak_language(language) - lang_data["can_understand"] = speaker.has_language(language) + lang_data["can_speak"] = !!speaker.has_language(language, SPOKEN_LANGUAGE) + lang_data["could_speak"] = !!(language_holder.omnitongue || speaker.could_speak_language(language)) + lang_data["can_understand"] = !!speaker.has_language(language, UNDERSTOOD_LANGUAGE) UNTYPED_LIST_ADD(data["languages"], lang_data) - if(check_rights_for(user.client, R_ADMIN) || isobserver(speaker)) - data["admin_mode"] = TRUE - data["omnitongue"] = language_holder.omnitongue - data["unknown_languages"] = list() - for(var/datum/language/language as anything in GLOB.all_languages) - if(language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE)) - continue - var/list/lang_data = list() - - lang_data["name"] = initial(language.name) - lang_data["desc"] = initial(language.desc) - lang_data["key"] = initial(language.key) - - UNTYPED_LIST_ADD(data["unknown_languages"], lang_data) + data["is_living"] = isliving(speaker) + data["admin_mode"] = check_rights_for(user.client, R_ADMIN) || isobserver(speaker) + data["omnitongue"] = language_holder.omnitongue return data @@ -60,7 +51,8 @@ . = ..() if(.) return - var/mob/user = usr + + var/mob/user = ui.user var/atom/movable/speaker = language_holder.owner var/is_admin = check_rights_for(user.client, R_ADMIN) var/language_name = params["language_name"] diff --git a/tgui/packages/tgui/interfaces/LanguageMenu.jsx b/tgui/packages/tgui/interfaces/LanguageMenu.jsx deleted file mode 100644 index 404ac8484ef..00000000000 --- a/tgui/packages/tgui/interfaces/LanguageMenu.jsx +++ /dev/null @@ -1,112 +0,0 @@ -import { Button, LabeledList, Section } from 'tgui-core/components'; - -import { useBackend } from '../backend'; -import { Window } from '../layouts'; - -export const LanguageMenu = (props) => { - const { act, data } = useBackend(); - const { - admin_mode, - is_living, - omnitongue, - languages = [], - unknown_languages = [], - } = data; - return ( - - -
- - {languages.map((language) => ( - - {!!is_living && ( -
- {!!admin_mode && ( -
act('toggle_omnitongue')} - /> - } - > - - {unknown_languages.map((language) => ( - - act('grant_language', { - language_name: language.name, - }) - } - /> - } - > - {language.desc} Key: ,{language.key}{' '} - {!!language.shadow && '(gained from mob)'}{' '} - {language.can_speak ? 'Can speak.' : 'Cannot speak.'} - - ))} - -
- )} -
-
- ); -}; diff --git a/tgui/packages/tgui/interfaces/LanguageMenu.tsx b/tgui/packages/tgui/interfaces/LanguageMenu.tsx new file mode 100644 index 00000000000..d134000ddd5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/LanguageMenu.tsx @@ -0,0 +1,276 @@ +import { + Box, + Button, + DmIcon, + Icon, + Section, + Stack, + Table, + Tooltip, +} from 'tgui-core/components'; +import { BooleanLike } from 'tgui-core/react'; + +import { useBackend } from '../backend'; +import { Window } from '../layouts'; + +type Language = { + name: string; + desc: string; + key: string; // the key used to speak the language + is_default: BooleanLike; // the user's selected default language + can_speak: BooleanLike; // mentally, we know how to speak it + could_speak: BooleanLike; // physically, we are capable of speaking it + can_understand: BooleanLike; // we can understand it regardless + icon: string; + icon_state: string; +}; + +type Data = { + is_living: BooleanLike; + admin_mode: BooleanLike; + omnitongue: BooleanLike; + languages: Language[]; +}; + +type LanguageProps = { + language: Language; +}; + +type LanguagePropsPassRest = LanguageProps & { + [key: string]: any; +}; + +const LangSpeakIcon = (props: LanguagePropsPassRest) => { + const { language, ...rest } = props; + return ( + + ); +}; + +const LangUnderstandIcon = (props: LanguageProps) => { + const { language } = props; + return ; +}; + +const LanguageNameAndDesc = (props: LanguageProps) => { + const { language } = props; + return language.desc ? ( + + + {language.name} + + + ) : ( + {language.name} + ); +}; + +const LanguageRow = (props: LanguageProps) => { + const { act, data } = useBackend(); + const { is_living, admin_mode } = data; + const { language } = props; + + return ( + + + {language.icon && language.icon_state ? ( + + + + + + + + + ) : ( + + )} + + + {!language.could_speak ? ( + + + + ) : ( + + )} + + + + + ,{language.key} + {!!is_living && ( + + + act('select_default', { + language_name: language.name, + }) + } + /> + + )} + {!!admin_mode && ( + + + + + )} + + ); +}; + +const OmnitongueToggle = (props) => { + const { act, data } = useBackend(); + const { omnitongue } = data; + return ( + + ); +}; + +export const LanguageMenu = (props) => { + const { data } = useBackend(); + const { admin_mode, is_living, languages } = data; + + // only show languages we can speak OR understand, UNLESS we're an admin + // also, push all languages we can speak to the top, then all languagse we can only understand, then alphabetize + const shown_languages = languages + .filter( + (language) => admin_mode || language.can_speak || language.can_understand, + ) + .sort( + (a, b) => + ((a.can_speak ? 1 : 0) - (b.can_speak ? 1 : 0)) * -2 + + (a.name > b.name ? 1 : 0), + ); + + return ( + + +
- Admin Mode - : null} + buttons={admin_mode ? : null} + fill + > + + + Name + Speak + Understand + + + + Key + + + + {!!is_living && ( + + + + Default + + + + )} + {!!admin_mode && } + + {shown_languages.map((language) => ( + + ))} +
+
+
+
+ ); +};