feat: Custom models editor with image picker and file browser integration#283
feat: Custom models editor with image picker and file browser integration#283ditschi wants to merge 4 commits intotoniebox-reverse-engineering:developfrom
Conversation
…tion - Full editor for tonies.custom.json (add, edit, delete entries) - Image management via reusable file browser (upload, select, custom_img) - Form validation, defaults, and localization
|
Thanks for the pr and the added functionality and following the “architecture” 👍 if it works fine, please remove the wip things from the old approach and set your editor as default. No need for a setting to switch between a not finished wip and a complete feature. Please stick to the icons in the action column instead of the text buttons, the gui should also work in mobile context. In the custom model file browser… according to the screenshot: are you using no modal and display the editor below the list? In case of a lot of images this might be not ideal? Why not using a modal there? Please also add an entry in the Changelog.md for your change. For my better understanding: can you explain the default image thing a bit for me? Aaah. I think I got it. Custom - tonies.custom.json and default - tonies.json. But maybe there is a better wording than default. Like original or so? have you test it with the image cache enabled? how did you integrate the image manager in teddystudio? Is the search for a tonie as image source still working as before? Or did you change that completely? - found it, only the custom image part from pure temporary to this solution (would be a completely temporary solution still a nice feature? Not sure probably not.) |
| onImagePreviewClick?: (imageUrl: string) => void; | ||
| } | ||
|
|
||
| const IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".webp", ".gif"]; |
There was a problem hiding this comment.
Move to constants.ts please
There was a problem hiding this comment.
Created constants/fileTypes.ts,
ditschi
left a comment
There was a problem hiding this comment.
will continue tomorrow with additionam manual tests (e.g. image cache)
| onImagePreviewClick?: (imageUrl: string) => void; | ||
| } | ||
|
|
||
| const IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".webp", ".gif"]; |
There was a problem hiding this comment.
Created constants/fileTypes.ts,
bdf2ed3 to
8555fb1
Compare
- Remove custom_editor_preview setting (editor always active) - Ignore contrib/data/www/ (compiled web assets) - Update teddycloud_web submodule (v0.7.0, PR feedback)
8555fb1 to
d382516
Compare
|
Updated description with updated screenshots |
|
Thanks for resolving the comments. Please use the default button colors (no green button for new model) |
| top: 0, | ||
| zIndex: 5, | ||
| background: "var(--ant-color-bg-container, #141414)", | ||
| border: "1px solid #303030", |
There was a problem hiding this comment.
No hardcoded colors please. Use the ants token system. Also direct use of those -var(…)
There was a problem hiding this comment.
Use e.g. token.colorBorder instead
| @@ -1559,10 +1545,22 @@ export const ToniesCustomJsonEditor: React.FC<ToniesCustomJsonEditorProps> = ({ | |||
| <div className="custom-tonie-table" style={{ border: "1px solid #303030", borderRadius: 8, padding: 8, marginBottom: 8 }}> | |||
There was a problem hiding this comment.
No hardcoded colors please
|
And please stick to the general placing of buttons. As far as I can remember nowhere else the buttons are on top for saving. They are always on the bottom. |
| let columns: any[] = [ | ||
| { | ||
| title: mode === "full" ? <div style={{ minHeight: 32 }}></div> : "", | ||
| title: mode === "full" ? t("fileBrowser.image", { defaultValue: "Bild" }) : "", |
There was a problem hiding this comment.
Please remove the default. (Or at least change to English)
| display: source === "original" ? "block" : "none", | ||
| maxHeight: 520, | ||
| overflowY: "auto", | ||
| border: "1px solid #303030", |
There was a problem hiding this comment.
No hardcoded colors please
| cursor: "pointer", | ||
| padding: 8, | ||
| border: | ||
| originalSelection === item ? "1px solid #1677ff" : "1px solid transparent", |
There was a problem hiding this comment.
No hardcoded colors please
There was a problem hiding this comment.
Is this a good idea to use this for adding files? This should be the light weight SELECT FILE file browser? So only for selecting existing files from teddycloud. Not for adding files.
With those changes it’s now kind of a duplicate to the filebrowser itself… I would prefer if you remove those changes and leave it as a select file filebrowser…
| const modelKey = entry.model.trim().toLowerCase(); | ||
| if (modelMap.has(modelKey)) { | ||
| return { | ||
| error: t("tonies.addNewCustomTonieModal.modelRequired") + ` (Duplikat: ${entry.model})`, |
| const pair = `${audioIds[j]}::${hashes[j].toLowerCase()}`; | ||
| if (pairMap.has(pair)) { | ||
| return { | ||
| error: `Doppelte audio_id+hash-Kombination erkannt: ${audioIds[j]}`, |
| const changedInputStyle = (changed: boolean) => | ||
| changed | ||
| ? ({ | ||
| backgroundColor: "rgba(250, 173, 20, 0.18)", |
There was a problem hiding this comment.
No hardcoded colors please, use the antd token system
|
|
||
| const getStatusBadge = (status: DraftStatus) => { | ||
| const label = getStatusLabel(status); | ||
| if (status === "clean") return <Tag style={{ background: "transparent", borderColor: "rgba(255,255,255,0.2)" }}>{label}</Tag>; |
There was a problem hiding this comment.
Try to use the antd token colors, no hardcoded colors.
| setPreviewOpen(true); | ||
| }} | ||
| style={{ | ||
| border: "1px solid #5a5a5a", |
There was a problem hiding this comment.
No hardcoded colors please
| }} | ||
| > | ||
| {isBroken ? ( | ||
| <span style={{ display: "block", fontSize: 18, lineHeight: "44px", textAlign: "center" }}>🖼️</span> |
There was a problem hiding this comment.
Only use antd icons please
| message={t("tonies.customEditor.batch.title", { defaultValue: "Batch editing active" })} | ||
| description={t("tonies.customEditor.batch.description", { | ||
| defaultValue: | ||
| "Bei Mehrfachauswahl werden nur Serie, Release, Sprache, Kategorie und Bild auf alle ausgewählten Modelle angewendet.", |
There was a problem hiding this comment.
No default please (and if you won’t remove it, stick to English)
| type="error" | ||
| showIcon | ||
| style={{ marginBottom: 8 }} | ||
| message={t("tonies.customEditor.validation.title", { defaultValue: "Please fix these issues first" })} |
There was a problem hiding this comment.
No default please. Makes it easier to identify missing translation entries)
| > | ||
| <Collapse.Panel | ||
| key="media" | ||
| header={t("tonies.customEditor.sections.media", { defaultValue: "Media and images" })} |
| {t("tonies.addNewCustomTonieModal.pic")} | ||
| <Tooltip | ||
| title={t("tonies.customEditor.picHint", { | ||
| defaultValue: |
| type="info" | ||
| showIcon | ||
| style={{ marginBottom: 12 }} | ||
| message={t("tonies.customEditor.coinHint.title", { defaultValue: "Hint: Audio assignment" })} |
| message={t("tonies.customEditor.coinHint.title", { defaultValue: "Hint: Audio assignment" })} | ||
| description={t("tonies.customEditor.coinHint.description", { | ||
| defaultValue: | ||
| "Optional – only for metadata (title, tracks). Custom coins work without a model. Use only custom audio – official IDs overwrite real Tonies. Does not link NFC tags to audio.", |
| <> | ||
| <div | ||
| style={{ | ||
| border: areTracksChanged ? "1px solid #faad14" : "1px solid transparent", |
There was a problem hiding this comment.
No hardcoded colors please
| setPendingSavePlan(null); | ||
| }} | ||
| onOk={handlePreflightConfirm} | ||
| okText={t("tonies.customEditor.preflight.confirm", { defaultValue: "Save now" })} |
| <Space direction="vertical"> | ||
| <Typography.Text> | ||
| {t("tonies.customEditor.preflight.description", { | ||
| defaultValue: "Please confirm the scope of this save operation.", |
There was a problem hiding this comment.
No default please (Also in the next lines)
There was a problem hiding this comment.
I hope you will refactor this file when you are finished? It’s a way too big. Move the functionality in one or more hooks please.
|
In general please use always the antd token colors if you want to set a color. Hardcoded colors are problematic if you switch the theme. I like to avoid default translations as it masks forgotten translations. As said earlier, you can use the gui —> community —> contribution —> translations to check if you have all translations in all 4 languages (not if you have missed one in all languages) Console error logs don’t need to be translated but should always be in English. I like the configurable columns in the models list. Are those chosen columns stored somewhere or do you have to select them always? (If the selection is stored somewhere, that might be a good thing for the filebrowser also) |


This Adds
DEPENDS ON:: Backend changes from toniebox-reverse-engineering/teddycloud#426
Details
Custom Tonies Editor: Editor for managing custom tonie models
Custom tonies editor

Custom modelsImage Manager:
Shared UI for selecting and managing images in Teddy Studio and Custom Tonies Editor
Image Editor::Original Images

Image Editor::Upload and manage Custom Images -- also available in Tonie Studio
