* Rich text editor and support for tagging objects (#340) * Preliminary work around making an Element type * Disabled Youtube code for now * Clean description with DOMPurify * Update GranblueElement with slug * Add new api endpoint for searching all resources * Add new variables and themes * Remove fixed height on html tag for now * Update README.md We renamed the folders for character images from `chara-` to `character-` * Add no results string * Add tiptap and associated packages * Update .gitignore * Update components that use character images * Add Editor component This commit adds the bulk of the code for our new rich-text editor. The Editor component will be used to edit and display rich text via Tiptap. * Add mention components This adds the code required for us to mention objects in rich text fields like team descriptions. The mentionSuggestion util fetches data from the server and serves it to MentionList for the user to select, then inserts it into the Editor as a token. * Implements Editor in edit team and team footer This implements the Editor component in EditPartyModal and PartyFooter. In PartyFooter, it is read-only. * Remove min-width on tokens * Add rudimentary conversion for old descriptions Old descriptions just translate as a blob of text, so we try to insert some paragraphs and newlines to keep things presentable and lessen the load if users decide to update * Add support for displaying jobs in MentionList * Handle numbers and value=0 better * Keep description reactive This shouldn't work? The snapshot should be the reactive one? I don't fucking know * Send locale to api with search query * Delete getLocale.tsx We didn't actually use this * Fix build errors * Override peer dependencies for tiptap mentions They haven't fixed the suggestion plugin, so we have to use a beta version * Fix background-color on CharacterRep * Tiptap updates (#343) * Reinstantiate editor on changes We can't dynamically update the content, so we have to recreate the Editor whenever something changes (page loads and updates) * Fix import @tiptap/core is different than @tiptap/react, who knew * Added several Tiptap components * Added a Remix icon that isn't in remixicon-react * Add colors for highlights * Add ToolbarButton component This is to standardize adding Toolbar icons so it wasn't a miserable mess in the Editor file * Add extensions and implement ToolbarButton * Remove unused code * Use party prop and add keys We always want to use the party in props until the transformer work is done and our source of truth is more reliable. Also, we are using keys to ensure that the component reloads on new page. * Component cleanup * Always use props.party * Ensure content gets reset when edits are committed Here, we do some tactical bandaid fixes to ensure that when the user saves data to the server, the editor will show the freshest data in both editable and read-only mode. In the Editor, its as easy as calling the setContent command in a useEffect hook when the content changes. In the party, we are saving party in a state and passing it down to the components via props. This is because the party prop we get from pages is only from the first time the server loaded data, so any edits are not reflected. The app state should have the latest updates, but due to reasons I don't completely understand, it is showing the old state first and then the one we want, causing the Editor to get stuck on old data. By storing the party in a state, we can populate the state from the server when the component mounts, then update it whenever the user saves data since all party data is saved in that component. * Fix build errors * Fix icon path * Remove duplicate binding * Fix styles * Update transcendence components to work with CSS modules (#350) * Update transcendence components to use CSS modules * Fix summon transcendence Summon transcendence was doing something wonky. This adapts the updateUncap endpoint method to make it a little bit clearer whats going on. * Add toolbar localizations * Allow translation of Heading icons * Show localized placeholder for team name * Add placeholder extension * Add placeholder to party description * Ensure name modification works right Needed a null check? for some reason?
596 lines
18 KiB
JSON
596 lines
18 KiB
JSON
{
|
|
"about": {
|
|
"segmented_control": {
|
|
"about": "About",
|
|
"updates": "Updates",
|
|
"roadmap": "Roadmap"
|
|
}
|
|
},
|
|
"accessories": {
|
|
"paladin": "shield",
|
|
"manadiver": "manatura"
|
|
},
|
|
"alert": {
|
|
"confirm_logout": "Are you sure you want to log out?",
|
|
"unsaved_changes": {
|
|
"party": "You will lose all changes to your party <strong>{objectName}</strong> if you continue.<br/><br/>Are you sure you want to continue without saving?",
|
|
"object": "You will lose all changes to <strong>{objectName}</strong> if you continue.<br/><br/>Are you sure you want to continue without saving?"
|
|
},
|
|
"incompatible_weapon": "You've selected a weapon that can't be added to the Additional Weapon slots."
|
|
},
|
|
"ax": {
|
|
"no_skill": "No AX Skill",
|
|
"errors": {
|
|
"value_too_low": "{{name}} must be at least {{minValue}}{{suffix}}",
|
|
"value_too_high": "{{name}} cannot be greater than {{maxValue}}{{suffix}}",
|
|
"value_not_whole": "{{name}} must be a whole number",
|
|
"value_empty": "{{name}} must have a value"
|
|
}
|
|
},
|
|
"awakening": {
|
|
"no_type": "No awakening",
|
|
"errors": {
|
|
"value_too_low": "Awakening level must be at least {{minValue}}",
|
|
"value_too_high": "Awakening level cannot be greater than {{maxValue}}",
|
|
"value_not_whole": "Awakening level must be a whole number",
|
|
"value_empty": "Awakening must have a level"
|
|
}
|
|
},
|
|
"buttons": {
|
|
"cancel": "Cancel",
|
|
"copy": "Copy link",
|
|
"confirm": "Got it",
|
|
"delete": "Delete team",
|
|
"show_info": "Edit info",
|
|
"hide_info": "Hide info",
|
|
"save_info": "Save info",
|
|
"remix": "Remix",
|
|
"save": "Save",
|
|
"saved": "Saved",
|
|
"menu": "Menu",
|
|
"new": "New",
|
|
"wiki": "View more on gbf.wiki"
|
|
},
|
|
"combobox": {
|
|
"selected": "Selected"
|
|
},
|
|
"context": {
|
|
"modify": {
|
|
"character": "Modify character",
|
|
"summon": "Modify summon",
|
|
"weapon": "Modify weapon"
|
|
},
|
|
"remove": "Remove from grid",
|
|
"remove_job_skill": "Remove class skill"
|
|
},
|
|
"dropdown": {
|
|
"party": {
|
|
"copy": "Copy link to team",
|
|
"delete": "Delete team",
|
|
"remix": "Remix team"
|
|
}
|
|
},
|
|
"earring": {
|
|
"errors": {
|
|
"value_too_low": "{{name}} must be at least {{minValue}}",
|
|
"value_too_high": "{{name}} cannot be greater than {{maxValue}}",
|
|
"value_not_whole": "{{name}} must be a whole number",
|
|
"value_empty": "{{name}} must have a value"
|
|
}
|
|
},
|
|
"elements": {
|
|
"null": "Null",
|
|
"wind": "Wind",
|
|
"fire": "Fire",
|
|
"water": "Water",
|
|
"earth": "Earth",
|
|
"dark": "Dark",
|
|
"light": "Light",
|
|
"full": {
|
|
"all": "All elements",
|
|
"null": "Null",
|
|
"wind": "Wind",
|
|
"fire": "Fire",
|
|
"water": "Water",
|
|
"earth": "Earth",
|
|
"dark": "Dark",
|
|
"light": "Light"
|
|
}
|
|
},
|
|
"errors": {
|
|
"internal_server_error": {
|
|
"title": "Internal Server Error",
|
|
"description": "The server reported a problem that we couldn't automatically recover from. Please try your request again."
|
|
},
|
|
"not_found": {
|
|
"title": "Not found",
|
|
"description": "The page you're looking for couldn't be found",
|
|
"button": "Create a new party"
|
|
},
|
|
"server_unavailable": {
|
|
"title": "Server unavailable",
|
|
"message": "We're having trouble connecting to the server right now",
|
|
"discord": "Join us on Discord for status updates"
|
|
},
|
|
"validation": {
|
|
"guidebooks": "You cannot equip more than one of each Sephira Guidebook"
|
|
},
|
|
"unauthorized": "You don't have permission to perform that action"
|
|
},
|
|
"filters": {
|
|
"name": "Filter",
|
|
"labels": {
|
|
"element": "Element",
|
|
"series": "Series",
|
|
"proficiency": "Proficiency",
|
|
"rarity": "Rarity"
|
|
}
|
|
},
|
|
"footer": {
|
|
"description": {
|
|
"label": "Description",
|
|
"empty": "This team doesn't have a description"
|
|
},
|
|
"remixes": {
|
|
"label_zero": "Remixes",
|
|
"label_one": "{{count}} Remix",
|
|
"label_other": "{{count}} Remixes",
|
|
"empty": "No one has remixed this team yet"
|
|
}
|
|
},
|
|
"header": {
|
|
"anonymous": "Anonymous",
|
|
"untitled_team": "Untitled team by {{username}}",
|
|
"new_team": "New team",
|
|
"byline": "{{partyName}} by {{username}}"
|
|
},
|
|
"job_skills": {
|
|
"all": "All skills",
|
|
"buffing": "Buffing",
|
|
"debuffing": "Debuffing",
|
|
"damaging": "Damaging",
|
|
"healing": "Healing",
|
|
"emp": "Extended Mastery",
|
|
"base": "Base Skills",
|
|
"state": {
|
|
"selectable": "Select a skill",
|
|
"no_skill": "No skill"
|
|
}
|
|
},
|
|
"menu": {
|
|
"about": "About",
|
|
"changelog": "Changelog",
|
|
"guides": "Guides",
|
|
"language": "Language",
|
|
"login": "Log in",
|
|
"roadmap": "Roadmap",
|
|
"profile": "Your profile",
|
|
"new": "New party",
|
|
"saved": "Saved",
|
|
"settings": "Settings",
|
|
"signup": "Sign up",
|
|
"teams": "Teams",
|
|
"logout": "Logout"
|
|
},
|
|
"modals": {
|
|
"about": {
|
|
"title": "About"
|
|
},
|
|
"roadmap": {
|
|
"title": "Roadmap"
|
|
},
|
|
"changelog": {
|
|
"title": "Changelog"
|
|
},
|
|
"characters": {
|
|
"title": "Character",
|
|
"subtitles": {
|
|
"ring": "Over Mastery",
|
|
"earring": "Aetherial Mastery",
|
|
"permanent": "Permanent Mastery",
|
|
"awakening": "Awakening"
|
|
},
|
|
"messages": {
|
|
"remove": "Are you sure you want to remove <strong>{{character}}</strong> from your team?"
|
|
},
|
|
"buttons": {
|
|
"confirm": "Save character",
|
|
"remove": "Remove character"
|
|
}
|
|
},
|
|
"conflict": {
|
|
"character": "Only one <strong>version of a character</strong> can be included in each party. Do you want to change your party members?",
|
|
"weapon": {
|
|
"generic": "Only one weapon from the <strong>{{series}} Series</strong> can be included in each party. Do you want to change your weapons?",
|
|
"opus-draconic": "Only one <strong>Dark Opus</strong> or <strong>Draconic Weapon</strong> can be included in each party. Do you want to change your weapons?"
|
|
},
|
|
"buttons": {
|
|
"confirm": "Confirm"
|
|
}
|
|
},
|
|
"edit_team": {
|
|
"title": "Edit team details",
|
|
"segments": {
|
|
"basic_info": "Basic info",
|
|
"properties": "Battle settings"
|
|
},
|
|
"buttons": {
|
|
"add_field": "Add field",
|
|
"confirm": "Save details"
|
|
},
|
|
"labels": {
|
|
"name": "Name",
|
|
"description": "Description",
|
|
"raid": "Battle",
|
|
"extra": "Additional weapons",
|
|
"charge_attack": "Charge Attack",
|
|
"full_auto": "Full Auto",
|
|
"auto_guard": "Auto Guard",
|
|
"auto_summon": "Auto Summon",
|
|
"turn_count": "Number of turns",
|
|
"button_count": "Number of buttons pressed",
|
|
"chain_count": "Number of chains",
|
|
"clear_time": "Clear time"
|
|
},
|
|
"descriptions": {
|
|
"extra": "Additional weapons are controlled by the selected battle"
|
|
},
|
|
"placeholders": {
|
|
"name": "Name your team",
|
|
"description": "Write some helpful notes about your team\n\nWhat's the turn rotation?\nWhat are some good unit subtitutions?"
|
|
},
|
|
"extra_notice": "You can add additional weapons to this team",
|
|
"extra_notice_guidebooks": "You can add additional weapons and Sephira Guidebooks to this team"
|
|
},
|
|
"delete_team": {
|
|
"title": "Delete team",
|
|
"description": "Are you sure you want to permanently delete this team?",
|
|
"buttons": {
|
|
"confirm": "Yes, delete",
|
|
"cancel": "Nevermind"
|
|
}
|
|
},
|
|
"filters": {
|
|
"title": "Advanced filters",
|
|
"labels": {
|
|
"charge_attack": "Charge Attack",
|
|
"full_auto": "Full Auto",
|
|
"auto_guard": "Auto Guard",
|
|
"max_buttons": "Maximum number of button presses",
|
|
"max_turns": "Maximum number of turns",
|
|
"min_characters": "Minimum number of characters",
|
|
"min_summons": "Minimum number of summons",
|
|
"min_weapons": "Minimum number of weapons",
|
|
"name_quality": "Hide untitled teams",
|
|
"user_quality": "Hide anonymous users",
|
|
"original_only": "Hide remixed teams"
|
|
},
|
|
"notice": "Filters set on <strong>user profiles</strong> and in <strong>your saved teams</strong> will not be saved",
|
|
"options": {
|
|
"on": "On",
|
|
"off": "Off",
|
|
"on_and_off": "On and Off"
|
|
},
|
|
"buttons": {
|
|
"confirm": "Save filters",
|
|
"clear": "Reset to default"
|
|
}
|
|
},
|
|
"guidebooks": {
|
|
"buttons": {
|
|
"remove": "Remove guidebook"
|
|
}
|
|
},
|
|
"job_skills": {
|
|
"messages": {
|
|
"remove": "Are you sure you want to remove <strong>{{job_skill}}</strong> from your team?"
|
|
},
|
|
"buttons": {
|
|
"remove": "Remove class skill"
|
|
}
|
|
},
|
|
"login": {
|
|
"title": "Log in",
|
|
"buttons": {
|
|
"confirm": "Log in"
|
|
},
|
|
"errors": {
|
|
"empty_email": "Please enter your email",
|
|
"empty_password": "Please enter your password",
|
|
"invalid_email": "That email address is not valid",
|
|
"invalid_credentials": "Your email address or password is incorrect"
|
|
},
|
|
"placeholders": {
|
|
"email": "Email address",
|
|
"password": "Password"
|
|
}
|
|
},
|
|
"remix_team": {
|
|
"title": "Remix team",
|
|
"description": {
|
|
"creator": "You're already the creator of <strong>{{name}}</strong>. Are you sure you want to make a copy by remixing it?",
|
|
"viewer": "Remixing a team makes a copy of it in your account so you can make your own changes.\n\nWould you like to remix <strong>{{name}}</strong>?"
|
|
},
|
|
"buttons": {
|
|
"confirm": "Yes, remix team",
|
|
"cancel": "Nevermind"
|
|
}
|
|
},
|
|
"settings": {
|
|
"title": "Account Settings",
|
|
"labels": {
|
|
"picture": "Picture",
|
|
"language": "Language",
|
|
"gender": "Main Character",
|
|
"private": "Private",
|
|
"theme": "Theme"
|
|
},
|
|
"descriptions": {
|
|
"picture": "Displayed next to your name",
|
|
"gender": "The character shown on your teams",
|
|
"private": "Hide your profile and prevent your grids from showing up in collections"
|
|
},
|
|
"gender": {
|
|
"gran": "Gran",
|
|
"djeeta": "Djeeta"
|
|
},
|
|
"language": {
|
|
"english": "English",
|
|
"japanese": "Japanese"
|
|
},
|
|
"theme": {
|
|
"light": "Light",
|
|
"dark": "Dark",
|
|
"system": "Follow system"
|
|
},
|
|
"buttons": {
|
|
"confirm": "Save settings"
|
|
}
|
|
},
|
|
"signup": {
|
|
"title": "Create an account",
|
|
"buttons": {
|
|
"confirm": "Sign up"
|
|
},
|
|
"agreement": "By signing up, I agree to the <br/><2>Privacy Policy</2> and <1>Usage Guidelines</1>.",
|
|
"errors": {
|
|
"field_in_use": "This {{field}} is already in use",
|
|
"empty_email": "Please enter your email",
|
|
"invalid_email": "That email address is not valid",
|
|
"username_too_short": "Username must be at least 3 characters",
|
|
"username_too_long": "Username must be less than 20 characters",
|
|
"empty_password": "Please enter your password",
|
|
"password_contains_username": "Your password should not contain your username",
|
|
"password_too_short": "Password must be at least 8 characters",
|
|
"mismatched_passwords": "Your passwords don't match"
|
|
},
|
|
"placeholders": {
|
|
"username": "Username",
|
|
"email": "Email address",
|
|
"password": "Password",
|
|
"password_confirm": "Password (again)"
|
|
}
|
|
},
|
|
"summon": {
|
|
"buttons": {
|
|
"remove": "Remove summon"
|
|
}
|
|
},
|
|
"weapon": {
|
|
"title": "Modify Weapon",
|
|
"buttons": {
|
|
"confirm": "Save weapon",
|
|
"remove": "Remove weapon"
|
|
},
|
|
"subtitles": {
|
|
"element": "Element",
|
|
"ax_skills": "AX Skills",
|
|
"awakening": "Awakening",
|
|
"weapon_keys": "Weapon Keys"
|
|
}
|
|
}
|
|
},
|
|
"page": {
|
|
"titles": {
|
|
"about": "About granblue.team",
|
|
"updates": "Updates / granblue.team",
|
|
"roadmap": "Roadmap / granblue.team",
|
|
"discover": "Discover teams / granblue.team",
|
|
"new": "Create a new team / granblue.team",
|
|
"profile": "@{{username}}'s Teams / granblue.team",
|
|
"team": "{{emoji}} {{teamName}} by {{username}} / granblue.team",
|
|
"saved": "Your saved teams / granblue.team"
|
|
},
|
|
"descriptions": {
|
|
"about": "More about granblue.team / Save and discover teams to use in Granblue Fantasy",
|
|
"updates": "Latest updates to granblue.team",
|
|
"roadmap": "Upcoming planned features for granblue.team",
|
|
"discover": "Save and discover teams to use in Granblue Fantasy and search by raid, element or recency",
|
|
"new": "Create and theorycraft teams to use in Granblue Fantasy and share with the community",
|
|
"profile": "Browse @{{username}}'s Teams and filter by raid, element or recency",
|
|
"team": "Browse this team for {{raidName}} by {{username}} and others on granblue.team"
|
|
}
|
|
},
|
|
"party": {
|
|
"segmented_control": {
|
|
"class": "Class",
|
|
"characters": "Characters",
|
|
"weapons": "Weapons",
|
|
"summons": "Summons"
|
|
},
|
|
"details": {
|
|
"labels": {
|
|
"charge_attack": "Charge Attack",
|
|
"full_auto": "Full Auto",
|
|
"auto_guard": "Auto Guard",
|
|
"auto_summon": "Auto Summon",
|
|
"turn_count": "Turn count",
|
|
"button_chain": "Buttons/Chains",
|
|
"clear_time": "Clear time"
|
|
},
|
|
"suffix": {
|
|
"buttons": "b",
|
|
"chains": "c",
|
|
"minutes": "m",
|
|
"seconds": "s"
|
|
},
|
|
"turns": {
|
|
"with_count_one": "{{count}} turn",
|
|
"with_count_other": "{{count}} turns"
|
|
}
|
|
}
|
|
},
|
|
"proficiencies": {
|
|
"sabre": "Sabre",
|
|
"dagger": "Dagger",
|
|
"spear": "Spear",
|
|
"axe": "Axe",
|
|
"staff": "Staff",
|
|
"gun": "Gun",
|
|
"melee": "Melee",
|
|
"bow": "Bow",
|
|
"harp": "Harp",
|
|
"katana": "Katana"
|
|
},
|
|
"raids": {
|
|
"all": "All battles",
|
|
"placeholder": "Select a raid...",
|
|
"sections": {
|
|
"raids": "Raids",
|
|
"solo": "Solo",
|
|
"events": "Events"
|
|
}
|
|
},
|
|
"rarities": {
|
|
"r": "R",
|
|
"sr": "SR",
|
|
"ssr": "SSR"
|
|
},
|
|
"recency": {
|
|
"all_time": "All time",
|
|
"last_day": "Last day",
|
|
"last_week": "Last week",
|
|
"last_month": "Last month",
|
|
"last_3_months": "Last 3 months",
|
|
"last_6_months": "Last 6 months",
|
|
"last_year": "Last year"
|
|
},
|
|
"saved": {
|
|
"title": "Your saved Teams",
|
|
"loading": "Loading saved teams...",
|
|
"not_found": "You haven't saved any teams"
|
|
},
|
|
"search": {
|
|
"recent": "Recently added",
|
|
"result_count": "{{record_count}} results",
|
|
"errors": {
|
|
"start_typing": "Start typing the name of a {{object}}",
|
|
"min_length": "Type at least 3 characters",
|
|
"no_results": "No results found for '{{query}}'",
|
|
"no_results_generic": "No results found",
|
|
"end_results": "No more results"
|
|
},
|
|
"placeholders": {
|
|
"weapon": "Search for a weapon...",
|
|
"summon": "Search for a summon...",
|
|
"character": "Search for a character...",
|
|
"job_skill": "Search class skills...",
|
|
"guidebook": "Search guidebooks...",
|
|
"raid": "Search battles..."
|
|
}
|
|
},
|
|
"series": {
|
|
"seraphic": "Seraphic",
|
|
"grand": "Grand",
|
|
"opus": "Dark Opus",
|
|
"draconic": "Draconic",
|
|
"primal": "Primal",
|
|
"olden_primal": "Olden Primal",
|
|
"beast": "Beast",
|
|
"omega": "Omega",
|
|
"regalia": "Regalia",
|
|
"militis": "Militis",
|
|
"xeno": "Xeno",
|
|
"astral": "Astral",
|
|
"rose": "Rose",
|
|
"hollowsky": "Hollowsky",
|
|
"ultima": "Ultima",
|
|
"bahamut": "Bahamut",
|
|
"epic": "Epic",
|
|
"ennead": "Ennead",
|
|
"cosmic": "Cosmic",
|
|
"ancestral": "Ancestral",
|
|
"superlative": "Superlative",
|
|
"vintage": "Vintage",
|
|
"class_champion": "Class Champion",
|
|
"sephira": "Sephira",
|
|
"new_world": "New World Foundation",
|
|
"revenant": "Revenant",
|
|
"proving": "Proven",
|
|
"disaster": "Revans",
|
|
"illustrious": "Illustrious",
|
|
"world": "World"
|
|
},
|
|
"summons": {
|
|
"main": "Main Summon",
|
|
"friend": "Friend Summon",
|
|
"summons": "Summons",
|
|
"subaura": "Sub Aura Summons"
|
|
},
|
|
"teams": {
|
|
"title": "Discover Teams",
|
|
"loading": "Loading teams...",
|
|
"not_found": "No teams found"
|
|
},
|
|
"toasts": {
|
|
"copied": "This party's URL was copied to your clipboard",
|
|
"remixed": "You remixed {{title}}",
|
|
"update": {
|
|
"title": "New update",
|
|
"description": {
|
|
"content": "New items have been added from the latest Granblue Fantasy update.",
|
|
"feature": "Now you can remix other people's teams, add Character rings and earrings, set Shields and Manatura on teams, and more!"
|
|
},
|
|
"button": "Learn more"
|
|
}
|
|
},
|
|
"tokens": {
|
|
"remix": "Remixed"
|
|
},
|
|
"toolbar": {
|
|
"tooltips": {
|
|
"bold": "Bold",
|
|
"italic": "Italic",
|
|
"strike": "Strikethrough",
|
|
"highlight": "Highlight",
|
|
"link": "Add a link",
|
|
"youtube": "Add a Youtube video",
|
|
"heading": "Heading {{level}}",
|
|
"bulletList": "Bullet list",
|
|
"orderedList": "Numbered list"
|
|
}
|
|
},
|
|
"tooltips": {
|
|
"copy_url": "Copy the URL to this team",
|
|
"new": "Create a new team",
|
|
"save": "Save this team to find later",
|
|
"remix": {
|
|
"create": "Make a copy of this team",
|
|
"source": "Go to original team",
|
|
"deleted": "The original team has been deleted"
|
|
}
|
|
},
|
|
"extra_weapons": "Additional Weapons",
|
|
"sephira_guidebooks": "Sephira Guidebooks",
|
|
"equipped": "Equipped",
|
|
"coming_soon": "Coming Soon",
|
|
"new_party": "New party",
|
|
"no_accessory": "No {{accessory}} equipped",
|
|
"no_title": "Untitled",
|
|
"no_raid": "No raid",
|
|
"no_user": "Anonymous",
|
|
"no_job": "No class",
|
|
"no_value": "No value",
|
|
"loading": "Loading...",
|
|
"level": "Level"
|
|
}
|