FEAT(ui): Channel/User description dock#6779
FEAT(ui): Channel/User description dock#6779jvbsl wants to merge 3 commits intomumble-voip:masterfrom
Conversation
779f447 to
4a96c8f
Compare
|
This looks really good. Thanks for working on it! One thing I noticed is that when resizing the dock, the avatar becomes too large, causing the content of the dock to overlap with the rest of the UI. Also, I think there should be a maximum size for the resizable image. |
|
Thanks for the feedback I get what you mean with a maximum size but could you please add a screenshot how it looks like when it overlaps, because I did not have that on my side, it just got big and the other content moved somewhere else(and could be scrolled at one point then). |
2d89293 to
9c09b7d
Compare
|
@RafGamer for me the window gets resized so that no actual overlap happens. But even that I think is not really nice. So I for now just set the maximum size of the avatar to 256x256, I think it is a reasonable size. |
This looks good. But I noticed that the avatar is only shown when the image is a png. It doesn't work when its a jpg and throws this warning: |
|
yes you are right, I completely forgot that I hardcoded that part: Need to look what a nice way would be because currently the actual conversion is in a completely different component |
Yeah, I saw that line but didn't know whether this was a bug or the intended behavior. Doesn't the texture contain a header? The Qt docs say that it can automatically guess the file format. |
|
Well yes but there seems to be some legacy image data format which gets converted in the overlay. So that's also what I'm using here to make sure that it was converted and in turn the image format is also set: @Krzmbrzl https://github.com/mumble-voip/mumble/blob/master/src/mumble/Overlay.cpp#L357 does it make sense to have this texture verification and conversion from this compressed raw format in the Overlay which is actually optional in the client? Shouldn't this happen even without this feature enabled? |
|
Yeah, I think doing the de-compression in code that may be excluded could likely cause issues. So it's probably better to just do the de-compression as soon as the texture is received 👀 |
88cbeaa to
b0be4ab
Compare
|
I didn't want to directly add it to the database and wanted to keep the change to be not to big to the previous code, but I now extracted the texture decoding into another class with the (bad) name of TextureManager. For now in a separate commit. |
b0be4ab to
97c2334
Compare
6e31c07 to
c394a6b
Compare
|
I guess I'm gonna make it ready for review, so that I can get some feedback on the code. Please be strict, because I only did it kind of iteratively so probably not the nicest code. And do tell if I should strip out the REFAC commit to another PR instead. Edit: damn forgot that I still had WIP in the commit message^ |
* Added a ImageWidget for showing a resizable image which keeps its aspect ratio * Changed user comment to be observable using signals * Added user/channel description dock * Add widgets to be translatable
Previously this was done in the overlay, which would mean the decoding of the textures in the legacy format could fail if the overlay is not configured to be compiled in.
c394a6b to
6be11aa
Compare
WalkthroughEncapsulates user comments behind getters/setters across client and server. Introduces TextureManager with global instance and refactors texture handling and overlay updates. Adds CommentViewWidget (UI, logic, and image widget) and wires it into MainWindow and message handling. Expands translations and updates build and scripts to include new widgets for lupdate. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as User
participant MW as MainWindow
participant CVW as CommentViewWidget
participant UM as UserModel
participant DB as Database
participant OL as Overlay
User->>MW: Select user/channel / UI event
MW->>CVW: updateCommentView(p, c)
alt User selected
CVW->>UM: request UserStats(session)
CVW->>DB: load comment/texture if missing
DB-->>CVW: comment/texture (optional)
CVW->>OL: updateOverlay() (if texture present)
CVW->>CVW: updateCommentContent(user, null)
Note over CVW: Connect to<br/>localNicknameChanged,<br/>commentChanged
else Channel view
CVW->>DB: load channel description if missing
DB-->>CVW: description (optional)
CVW->>CVW: updateCommentContent(null, channel)
Note over CVW: Subscribe to channel<br/>entered/exited to refresh
end
sequenceDiagram
autonumber
participant Net as Network
participant MSG as Messages/UserModel
participant TM as TextureManager
participant G as Global.textureManager
participant OL as Overlay
Net-->>MSG: UserState with texture or hash
MSG->>G: get TextureManager
MSG->>TM: convertTexture(blob, out format)
TM-->>MSG: converted blob or empty
alt converted non-empty
MSG->>MSG: set qbaTexture/qbaTextureHash
MSG->>OL: updateOverlay()
else empty
MSG->>Net: RequestBlob (texture)
end
sequenceDiagram
autonumber
participant RPC as RPC::setUserState
participant SU as ServerUser
participant S as Server
RPC->>SU: compare comment vs qsComment()
alt changed
RPC->>S: hashAssign(SU.qbaCommentHash, newComment)
S-->>RPC: returns newComment (ref)
RPC->>SU: setComment(returned QString)
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.38.6)src/mumble/mumble_ar.tssrc/mumble/mumble_bg.tssrc/mumble/mumble_br.ts
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 147
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (21)
src/mumble/mumble_fi.ts (5)
1643-1658: Complete listener-attenuation option stringsThese appear in a user-facing selector. Unfinished entries will fall back to English and break consistency.
Apply this diff:
- <source>at</source> - <translation type="unfinished"></translation> + <source>at</source> + <translation>tasolla</translation> @@ - <source>while someone in your channel talks</source> - <translation type="unfinished"></translation> + <source>while someone in your channel talks</source> + <translation>kun joku kanavallasi puhuu</translation> @@ - <source>always</source> - <translation type="unfinished"></translation> + <source>always</source> + <translation>aina</translation> @@ - <source>Attenuate listeners by...</source> - <translation type="unfinished"></translation> + <source>Attenuate listeners by...</source> + <translation>Vaimenna kuuntelijoita...</translation>
5063-5093: Finish TalkingUI background controls translationsComplete these to keep the Look & Feel page fully localized.
Apply this diff:
- <source>Clears the TalkingUI background setting.</source> - <translation type="unfinished"></translation> + <source>Clears the TalkingUI background setting.</source> + <translation>Tyhjentää Puhujalistan tausta-asetuksen.</translation> @@ - <source>Clear Background Color</source> - <translation type="unfinished"></translation> + <source>Clear Background Color</source> + <translation>Tyhjennä taustaväri</translation> @@ - <source>Clear</source> - <translation type="unfinished">Tyhjennä</translation> + <source>Clear</source> + <translation>Tyhjennä</translation> @@ - <source>Color that gets used for the background of the talkingUI.</source> - <translation type="unfinished"></translation> + <source>Color that gets used for the background of the talkingUI.</source> + <translation>Puhujalistan taustana käytettävä väri.</translation> @@ - <source>Choose</source> - <translation type="unfinished"></translation> + <source>Choose</source> + <translation>Valitse</translation> @@ - <source>Background color that, if set, overrides the theme background color.</source> - <translation type="unfinished"></translation> + <source>Background color that, if set, overrides the theme background color.</source> + <translation>Taustaväri, joka asetettuna ohittaa teeman taustavärin.</translation> @@ - <source>Background Color</source> - <translation type="unfinished"></translation> + <source>Background Color</source> + <translation>Taustaväri</translation> @@ - <source>Choose a Color</source> - <translation type="unfinished"></translation> + <source>Choose a Color</source> + <translation>Valitse väri</translation>
5095-5150: Finish Dark/Light theme configuration translationsNew theme-related strings are all unfinished. Provide concise Finnish equivalents.
Apply this diff:
- <source>Dark theme to use to style the user interface</source> - <translation type="unfinished"></translation> + <source>Dark theme to use to style the user interface</source> + <translation>Tumma teema käyttöliittymän tyylitykseen</translation> @@ - <source><b>Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme</b><br />Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source> - <translation type="unfinished"></translation> + <source><b>Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme</b><br />Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source> + <translation><b>Määrittää millä teemalla Mumblen käyttöliittymä tyylitellään tummassa tilassa</b><br />Mumble hakee teemoja tietyistä hakemistoista ja näyttää ne tässä luettelossa. Valittua teemaa käytetään ulkoasun (värit, kuvakkeet jne.) mukauttamiseen.</translation> @@ - <source>Light theme to use to style the user interface</source> - <translation type="unfinished"></translation> + <source>Light theme to use to style the user interface</source> + <translation>Vaalea teema käyttöliittymän tyylitykseen</translation> @@ - <source>Dark Theme</source> - <translation type="unfinished"></translation> + <source>Dark Theme</source> + <translation>Tumma teema</translation> @@ - <source>Sets the theme automatically based on the system theme.</source> - <translation type="unfinished"></translation> + <source>Sets the theme automatically based on the system theme.</source> + <translation>Asettaa teeman automaattisesti järjestelmän teeman perusteella.</translation> @@ - <source>Automatic theme based on system theme</source> - <translation type="unfinished"></translation> + <source>Automatic theme based on system theme</source> + <translation>Automaattinen teema järjestelmän teeman mukaan</translation> @@ - <source>Auto</source> - <translation type="unfinished"></translation> + <source>Auto</source> + <translation>Automaattinen</translation> @@ - <source>Sets the theme to the configured dark theme setting</source> - <translation type="unfinished"></translation> + <source>Sets the theme to the configured dark theme setting</source> + <translation>Ottaa käyttöön määritetyn tumman teeman</translation> @@ - <source>Dark</source> - <translation type="unfinished"></translation> + <source>Dark</source> + <translation>Tumma</translation> @@ - <source>Sets the theme to the configured light theme setting</source> - <translation type="unfinished"></translation> + <source>Sets the theme to the configured light theme setting</source> + <translation>Ottaa käyttöön määritetyn vaalean teeman</translation> @@ - <source>Light Theme</source> - <translation type="unfinished"></translation> + <source>Light Theme</source> + <translation>Vaalea teema</translation> @@ - <source>Light</source> - <translation type="unfinished"></translation> + <source>Light</source> + <translation>Vaalea</translation> @@ - <source>Open the themes directory in the systems file manager</source> - <translation type="unfinished"></translation> + <source>Open the themes directory in the systems file manager</source> + <translation>Avaa teemakansio tiedostonhallinnassa</translation> @@ - <source>Open Themes Directory</source> - <translation type="unfinished"></translation> + <source>Open Themes Directory</source> + <translation>Avaa teemakansio</translation>
9619-9654: Complete UserInformation statistics stringsThese appear in the connection stats. Provide final translations and remove unfinished flags.
Apply this diff:
- <source>to client rolling average</source> - <translation type="unfinished"></translation> + <source>to client rolling average</source> + <translation>Ohjelmalle liukuva keskiarvo</translation> @@ - <source>Last X minutes:</source> - <translation type="unfinished"></translation> + <source>Last X minutes:</source> + <translation>Viimeiset X minuuttia:</translation> @@ - <source>% lost</source> - <translation type="unfinished"></translation> + <source>% lost</source> + <translation>% hävikkiä</translation> @@ - <source>from client rolling average</source> - <translation type="unfinished"></translation> + <source>from client rolling average</source> + <translation>Ohjelmalta liukuva keskiarvo</translation> @@ - <source>% late</source> - <translation type="unfinished"></translation> + <source>% late</source> + <translation>% myöhässä</translation> @@ - <source>Total:</source> - <translation type="unfinished"></translation> + <source>Total:</source> + <translation>Yhteensä:</translation> @@ - <source>Last %1 %2:</source> - <translation type="unfinished"></translation> + <source>Last %1 %2:</source> + <translation>Viimeiset %1 %2:</translation> @@ - <source>seconds</source> - <translation type="unfinished">sekuntia</translation> + <source>seconds</source> + <translation>sekuntia</translation> @@ - <source>minutes</source> - <translation type="unfinished"></translation> + <source>minutes</source> + <translation>minuuttia</translation>
10124-10131: Localize new Voice Recorder output modes (JACK)Finish these labels to match existing recorder terminology.
Apply this diff:
- <source>Multichannel + Transport (JACK)</source> - <translation type="unfinished"></translation> + <source>Multichannel + Transport (JACK)</source> + <translation>Monikanava + kuljetus (JACK)</translation> @@ - <source>Transport (JACK, standalone)</source> - <translation type="unfinished"></translation> + <source>Transport (JACK, standalone)</source> + <translation>Kuljetus (JACK, erillinen)</translation>scripts/updatetranslations.py (1)
86-88: Bug: bytes/str concatenation in error path crashes on lupdate failure.logging.debug('stdout: ' + res.stdout) will raise a TypeError (str + bytes). This masks the real lupdate error and can break CI diagnostics.
Apply this diff:
@@ - if debuglupdate: - logging.debug(res.stdout) + if debuglupdate: + logging.debug('lupdate stdout:\n%s', res.stdout.decode('utf-8', errors='replace')) + logging.debug('lupdate stderr:\n%s', res.stderr.decode('utf-8', errors='replace')) if res.returncode != 0: logging.error('lupdate failed with error code %d', res.returncode) - logging.debug('stdout: ' + res.stdout) - exit(1) + logging.debug('lupdate stdout:\n%s', res.stdout.decode('utf-8', errors='replace')) + logging.debug('lupdate stderr:\n%s', res.stderr.decode('utf-8', errors='replace')) + sys.exit(1)src/mumble/mumble_tr.ts (2)
7291-7301: Provide translations for image dialog stringsThese user-facing strings are currently unfinished.
Apply this diff:
- <source>Open Image</source> - <translation type="unfinished"></translation> + <source>Open Image</source> + <translation>Görsel Aç</translation> @@ - <source>Error</source> - <translation type="unfinished"></translation> + <source>Error</source> + <translation>Hata</translation> @@ - <source>Failed to decode image.</source> - <translation type="unfinished"></translation> + <source>Failed to decode image.</source> + <translation>Görsel çözümlenemedi.</translation>
1-10175: Unfinished translations found — please complete before releaseQuick summary: src/mumble/mumble_tr.ts contains translation nodes still marked type="unfinished" in several newly introduced contexts. These must be translated or the unfinished attribute removed before release.
Files/contexts and source strings requiring attention:
- src/mumble/mumble_tr.ts — AccessibleQGroupBox
- "empty"
- src/mumble/mumble_tr.ts — CommentViewWidget
- "Title"
- "Users"
- "Properties"
- "OS"
- "Version"
- "Description:"
- "This is a test text"
- "Comment"
- "Description"
- "%1 (%2)"
- src/mumble/mumble_tr.ts — MainWindow
- long usage/help block starting "Usage: mumble [options] [...]" (entire block is unfinished)
- "Adaptive Push"
- "When using the push-to-talk transmission mode, this will act as the push-to-talk action. Otherwise, it will act as a push-to-mute action."
- "Open Image"
- "Error"
- "Failed to decode image."
- "Comment"
- src/mumble/mumble_tr.ts — ResponsiveImageDialog
- "Image Preview"
- src/mumble/mumble_tr.ts — TrayIcon
- "Show"
- "Hide"
Action required:
- Provide Turkish translations for the empty entries and/or finish the existing translations.
- Remove type="unfinished" from translation nodes that are complete.
- Re-run a check (e.g. rg -n 'type="unfinished"' src/mumble/mumble_tr.ts) and ensure no unfinished entries remain in these contexts.
src/mumble/mumble_te.ts (3)
71-79: Correct “Password” translation and remove stray line breaksCurrent translation “సాంకేతిక పదం” is incorrect for “Password” and includes extra newlines that degrade readability.
<message> <source>Password</source> - <translation>సాంకేతిక పదం - - - - - -</translation> + <translation>పాస్వర్డ్</translation> </message>
27-29: Fix obvious mistranslations and typos in early ACLEditor stringsThese are user-facing staples and currently misleading or machine-transliterated.
@@ - <translation>సడలించు సర్వర్ విలువ</translation> + <translation>డిఫాల్ట్ సర్వర్ విలువ</translation> @@ - <translation> కధనం</translation> + <translation>వివరణ</translation> @@ - <translation>అనిత్యమైన</translation> + <translation>తాత్కాలికం</translation> @@ - <translation>తల్లితండ్రి నుంచి వారసత్వ జాబితసంక్య</translation> + <translation>మాతృ ఛానల్ నుండి గ్రూప్ సభ్యులను వారసత్వంగా పొందు</translation> @@ - <translation>గ్రూప్ వజ్ ఇణెరిటెడ్ బై పెరెంట్ పెరెంట్</translation> + <translation>సమూహం మాతృ ఛానల్ నుండి వారసత్వంగా పొందబడింది</translation>Rationale: fixes wrong meaning, spelling, and transliterations, improving clarity and consistency.
Also applies to: 67-69, 89-91, 124-126, 140-142
43-45: Fix placeholder formatting in Telugu translationsThe translation strings at the following locations include spaces between the
%and the placeholder index, which will break runtime formatting and triggerlreleasewarnings. Please update them to use%1and%2exactly (no intervening spaces), and adjust the Telugu wording as needed:• File:
src/mumble/mumble_te.ts, lines 43–45- <translation>ఇది% 1 హక్కును మంజూరు చేస్తుంది. ఒక విశేషణం అనుమతి మరియు తిరస్కరించబడినట్లయితే, అది ఖండించబడింది. <br />% 2</translation> + <translation>ఇది %1 హక్కును మంజూరు చేస్తుంది. ఒక అధికారం అనుమతించి కూడా తిరస్కరించబడితే, అది తిరస్కరించబడినట్లే ఉంటుంది. <br />%2</translation>• File:
src/mumble/mumble_te.ts, lines 51–53- <translation type="unfinished"></translation> + <translation>ఇది %1 హక్కును రద్దు చేస్తుంది. ఒక అధికారం అనుమతించి కూడా తిరస్కరించబడితే, అది తిరస్కరించబడినట్లే ఉంటుంది. <br />%2</translation>After applying these changes, please run
lreleaseto verify there are no remaining placeholder mismatches.src/mumble/mumble_uk.ts (1)
5096-5151: Provide translations for new Theme selection controls (Dark/Light/Auto).Missing translations leave parts of the new theming UI in English. Suggestions below keep terminology consistent with the rest of the settings pages.
- <source>Dark theme to use to style the user interface</source> - <translation type="unfinished"></translation> + <source>Dark theme to use to style the user interface</source> + <translation>Темна тема для оформлення інтерфейсу користувача</translation> @@ - <source><b>Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme</b><br />Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source> - <translation type="unfinished"></translation> + <source><b>Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme</b><br />Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source> + <translation><b>Визначає, якою темною темою оформлювати інтерфейс Mumble</b><br />Mumble знаходить теми у певних каталогах і показує їх у цьому списку. Обрана тема застосовується до зовнішнього вигляду програми (кольори, піктограми тощо).</translation> @@ - <source>Light theme to use to style the user interface</source> - <translation type="unfinished"></translation> + <source>Light theme to use to style the user interface</source> + <translation>Світла тема для оформлення інтерфейсу користувача</translation> @@ - <source>Dark Theme</source> - <translation type="unfinished"></translation> + <source>Dark Theme</source> + <translation>Темна тема</translation> @@ - <source>Sets the theme automatically based on the system theme.</source> - <translation type="unfinished"></translation> + <source>Sets the theme automatically based on the system theme.</source> + <translation>Автоматично встановлює тему на основі системної теми.</translation> @@ - <source>Automatic theme based on system theme</source> - <translation type="unfinished"></translation> + <source>Automatic theme based on system theme</source> + <translation>Автоматичне визначення теми за системною</translation> @@ - <source>Auto</source> - <translation type="unfinished"></translation> + <source>Auto</source> + <translation>Авто</translation> @@ - <source>Sets the theme to the configured dark theme setting</source> - <translation type="unfinished"></translation> + <source>Sets the theme to the configured dark theme setting</source> + <translation>Перемикає на налаштовану темну тему</translation> @@ - <source>Dark</source> - <translation type="unfinished"></translation> + <source>Dark</source> + <translation>Темна</translation> @@ - <source>Sets the theme to the configured light theme setting</source> - <translation type="unfinished"></translation> + <source>Sets the theme to the configured light theme setting</source> + <translation>Перемикає на налаштовану світлу тему</translation> @@ - <source>Light Theme</source> - <translation type="unfinished"></translation> + <source>Light Theme</source> + <translation>Світла тема</translation> @@ - <source>Light</source> - <translation type="unfinished"></translation> + <source>Light</source> + <translation>Світла</translation> @@ - <source>Open the themes directory in the systems file manager</source> - <translation type="unfinished"></translation> + <source>Open the themes directory in the systems file manager</source> + <translation>Відкрити каталог тем у файловому менеджері системи</translation> @@ - <source>Open Themes Directory</source> - <translation type="unfinished"></translation> + <source>Open Themes Directory</source> + <translation>Відкрити каталог тем</translation>src/mumble/mumble_ca.ts (7)
1639-1658: Translate new attenuation strings (AudioOutput: listener attenuation controls)Untranslated labels impact UX. Proposed translations:
- “at” → “a”
- “while someone in your channel talks” → “mentre algú del vostre canal parla”
- “always” → “sempre”
- “Attenuate listeners by...” → “Atenua els oients en...”
- <source>at</source> - <translation type="unfinished"></translation> + <source>at</source> + <translation>a</translation> - <source>while someone in your channel talks</source> - <translation type="unfinished"></translation> + <source>while someone in your channel talks</source> + <translation>mentre algú del vostre canal parla</translation> - <source>always</source> - <translation type="unfinished"></translation> + <source>always</source> + <translation>sempre</translation> - <source>Attenuate listeners by...</source> - <translation type="unfinished"></translation> + <source>Attenuate listeners by...</source> + <translation>Atenua els oients en...</translation>
5063-5093: Complete LookConfig color/theme translationsThese are visible UI controls; finish them and keep terminology consistent with earlier “Talking UI” = “Interfície de la parla”.
- <source>Clears the TalkingUI background setting.</source> - <translation type="unfinished"></translation> + <source>Clears the TalkingUI background setting.</source> + <translation>Esborra la configuració del fons de la Interfície de la parla.</translation> - <source>Clear Background Color</source> - <translation type="unfinished"></translation> + <source>Clear Background Color</source> + <translation>Esborra el color de fons</translation> - <source>Clear</source> - <translation type="unfinished"></translation> + <source>Clear</source> + <translation>Neteja</translation> - <source>Color that gets used for the background of the talkingUI.</source> - <translation type="unfinished"></translation> + <source>Color that gets used for the background of the talkingUI.</source> + <translation>Color utilitzat per al fons de la Interfície de la parla.</translation> - <source>Choose</source> - <translation type="unfinished"></translation> + <source>Choose</source> + <translation>Tria</translation> - <source>Background color that, if set, overrides the theme background color.</source> - <translation type="unfinished"></translation> + <source>Background color that, if set, overrides the theme background color.</source> + <translation>Color de fons que, si s’estableix, sobreescriu el color de fons del tema.</translation> - <source>Background Color</source> - <translation type="unfinished"></translation> + <source>Background Color</source> + <translation>Color de fons</translation> - <source>Choose a Color</source> - <translation type="unfinished"></translation> + <source>Choose a Color</source> + <translation>Trieu un color</translation> - <source>Dark theme to use to style the user interface</source> - <translation type="unfinished"></translation> + <source>Dark theme to use to style the user interface</source> + <translation>Tema fosc per estilitzar la interfície d’usuari</translation> - <source><b>Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme</b>... - <translation type="unfinished"></translation> + <source><b>Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme</b>... + <translation><b>Configura amb quin tema s’ha d’estilitzar la interfície d’usuari del Mumble quan s’utilitza el tema fosc</b>...</translation> - <source>Light theme to use to style the user interface</source> - <translation type="unfinished"></translation> + <source>Light theme to use to style the user interface</source> + <translation>Tema clar per estilitzar la interfície d’usuari</translation> - <source>Dark Theme</source> - <translation type="unfinished"></translation> + <source>Dark Theme</source> + <translation>Tema fosc</translation> - <source>Sets the theme automatically based on the system theme.</source> - <translation type="unfinished"></translation> + <source>Sets the theme automatically based on the system theme.</source> + <translation>Estableix el tema automàticament segons el tema del sistema.</translation> - <source>Automatic theme based on system theme</source> - <translation type="unfinished"></translation> + <source>Automatic theme based on system theme</source> + <translation>Tema automàtic segons el tema del sistema</translation> - <source>Auto</source> - <translation type="unfinished"></translation> + <source>Auto</source> + <translation>Automàtic</translation> - <source>Sets the theme to the configured dark theme setting</source> - <translation type="unfinished"></translation> + <source>Sets the theme to the configured dark theme setting</source> + <translation>Estableix el tema al tema fosc configurat</translation> - <source>Dark</source> - <translation type="unfinished"></translation> + <source>Dark</source> + <translation>Fosc</translation> - <source>Sets the theme to the configured light theme setting</source> - <translation type="unfinished"></translation> + <source>Sets the theme to the configured light theme setting</source> + <translation>Estableix el tema al tema clar configurat</translation> - <source>Light Theme</source> - <translation type="unfinished"></translation> + <source>Light Theme</source> + <translation>Tema clar</translation> - <source>Light</source> - <translation type="unfinished"></translation> + <source>Light</source> + <translation>Clar</translation> - <source>Open the themes directory in the systems file manager</source> - <translation type="unfinished"></translation> + <source>Open the themes directory in the systems file manager</source> + <translation>Obre la carpeta de temes al gestor de fitxers del sistema</translation> - <source>Open Themes Directory</source> - <translation type="unfinished"></translation> + <source>Open Themes Directory</source> + <translation>Obre la carpeta de temes</translation>
7166-7185: Translate “Move back” action and keep acceleratorAdd Catalan with an accelerator. Proposal uses “&Torna enrere”.
- <source>M&ove back</source> - <translation type="unfinished"></translation> + <source>M&ove back</source> + <translation>&Torna enrere</translation> - <source>Moves you back to the previous channel</source> - <translation type="unfinished"></translation> + <source>Moves you back to the previous channel</source> + <translation>Us torna al canal anterior</translation> - <source>Move back</source> - <comment>Global shortcut</comment> - <translation type="unfinished"></translation> + <source>Move back</source> + <comment>Global shortcut</comment> + <translation>Torna enrere</translation> - <source>This will move you back into your previous channel</source> - <translation type="unfinished"></translation> + <source>This will move you back into your previous channel</source> + <translation>Això us retornarà al vostre canal anterior</translation> - <source>The channel you have been in previously no longer exists on this server.</source> - <translation type="unfinished"></translation> + <source>The channel you have been in previously no longer exists on this server.</source> + <translation>El canal en què éreu anteriorment ja no existeix en aquest servidor.</translation>
7187-7212: Translate listener attenuation hotkeysAdd concise, consistent phrases.
- <source>Cycle listener attenuation mode</source> - <comment>Global shortcut</comment> - <translation type="unfinished"></translation> + <source>Cycle listener attenuation mode</source> + <comment>Global shortcut</comment> + <translation>Canvia el mode d’atenuació dels oients</translation> - <source>This will cycle through the different attenuation modes for channel listeners</source> - <translation type="unfinished"></translation> + <source>This will cycle through the different attenuation modes for channel listeners</source> + <translation>Això recorrerà els diferents modes d’atenuació per als oients del canal</translation> - <source>Listener attenuation up (+10%)</source> - <comment>Global shortcut</comment> - <translation type="unfinished"></translation> + <source>Listener attenuation up (+10%)</source> + <comment>Global shortcut</comment> + <translation>Atenuació dels oients amunt (+10%)</translation> - <source>This increases the attenuation of channel listeners by 10 percents points</source> - <translation type="unfinished"></translation> + <source>This increases the attenuation of channel listeners by 10 percents points</source> + <translation>Això augmenta l’atenuació dels oients del canal en 10 punts percentuals</translation> - <source>Listener attenuation down (-10%)</source> - <comment>Global shortcut</comment> - <translation type="unfinished"></translation> + <source>Listener attenuation down (-10%)</source> + <comment>Global shortcut</comment> + <translation>Atenuació dels oients avall (-10%)</translation> - <source>This decreases the attenuation of channel listeners by 10 percents points</source> - <translation type="unfinished"></translation> + <source>This decreases the attenuation of channel listeners by 10 percents points</source> + <translation>Això redueix l’atenuació dels oients del canal en 10 punts percentuals</translation>
7282-7290: Translate “Adaptive Push” shortcut- <source>Adaptive Push</source> - <comment>Global Shortcut</comment> - <translation type="unfinished"></translation> + <source>Adaptive Push</source> + <comment>Global Shortcut</comment> + <translation>Pulsació adaptativa</translation> - <source>When using the push-to-talk transmission mode, this will act as the push-to-talk action. Otherwise, it will act as a push-to-mute action.</source> - <comment>Global Shortcut</comment> - <translation type="unfinished"></translation> + <source>When using the push-to-talk transmission mode, this will act as the push-to-talk action. Otherwise, it will act as a push-to-mute action.</source> + <comment>Global Shortcut</comment> + <translation>Quan utilitzeu el mode Prémer per parlar, actuarà com a acció de Prémer per parlar. En cas contrari, actuarà com a acció de Prémer per silenciar.</translation>
7292-7302: Translate image error messages- <source>Open Image</source> - <translation type="unfinished"></translation> + <source>Open Image</source> + <translation>Obre la imatge</translation> - <source>Error</source> - <translation type="unfinished"></translation> + <source>Error</source> + <translation>Error</translation> - <source>Failed to decode image.</source> - <translation type="unfinished"></translation> + <source>Failed to decode image.</source> + <translation>No s’ha pogut descodificar la imatge.</translation>
9619-9654: Translate UserInformation rolling-average stats- <source>to client rolling average</source> - <translation type="unfinished"></translation> + <source>to client rolling average</source> + <translation>mitjana mòbil cap al client</translation> - <source>Last X minutes:</source> - <translation type="unfinished"></translation> + <source>Last X minutes:</source> + <translation>Darrers X minuts:</translation> - <source>% lost</source> - <translation type="unfinished"></translation> + <source>% lost</source> + <translation>% perdut</translation> - <source>from client rolling average</source> - <translation type="unfinished"></translation> + <source>from client rolling average</source> + <translation>mitjana mòbil des del client</translation> - <source>% late</source> - <translation type="unfinished"></translation> + <source>% late</source> + <translation>% tard</translation> - <source>Total:</source> - <translation type="unfinished"></translation> + <source>Total:</source> + <translation>Total:</translation> - <source>Last %1 %2:</source> - <translation type="unfinished"></translation> + <source>Last %1 %2:</source> + <translation>Darrers %1 %2:</translation> - <source>minutes</source> - <translation type="unfinished"></translation> + <source>minutes</source> + <translation>minuts</translation>src/murmur/Server.cpp (1)
2818-2839: In-memory user comment is not updated; also remove ineffective std::move on constsetComment updates qbaCommentHash and persists to DB but never updates the ServerUser’s in-memory comment, causing stale state until a reload. Also, std::move(comment) on a const QString is a no-op and obscures intent.
Apply both fixes:
bool Server::setComment(ServerUser &user, const QString &comment) { - hashAssign(user.qbaCommentHash, comment); + user.setComment(hashAssign(user.qbaCommentHash, comment)); if (user.iId <= 0) { return false; } QMap< int, QString > info; - info.insert(static_cast< int >(::mumble::server::db::UserProperty::Comment), std::move(comment)); + info.insert(static_cast< int >(::mumble::server::db::UserProperty::Comment), comment);This keeps the in-memory object consistent with what we store/emit.
src/mumble/mumble_es.ts (1)
7293-7307: Localize new image-dialog strings.These are user-visible errors and actions; translate and drop unfinished flags.
Apply this diff:
- <source>Open Image</source> - <translation type="unfinished"></translation> + <source>Open Image</source> + <translation>Abrir imagen</translation> - <source>Error</source> - <translation type="unfinished"></translation> + <source>Error</source> + <translation>Error</translation> - <source>Failed to decode image.</source> - <translation type="unfinished"></translation> + <source>Failed to decode image.</source> + <translation>No se pudo decodificar la imagen.</translation> - <source>Comment</source> - <translation type="unfinished"></translation> + <source>Comment</source> + <translation>Comentario</translation>
| if (!user->qsComment().isEmpty()) { | ||
| if (user->qsComment().length() <= 20) { | ||
| description += QString("%1,").arg(user->qsComment()); | ||
| } else { | ||
| description += QString("%1,").arg(QObject::tr("has a long comment")); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Strip HTML from comments before exposing to assistive tech
Comments may contain HTML. Feeding markup into screen readers degrades accessibility. Use the existing removeHTMLTags() helper and avoid repeated accessor calls.
- if (!user->qsComment().isEmpty()) {
- if (user->qsComment().length() <= 20) {
- description += QString("%1,").arg(user->qsComment());
+ const QString comment = removeHTMLTags(user->qsComment());
+ if (!comment.isEmpty()) {
+ if (comment.length() <= 20) {
+ description += QString("%1,").arg(comment);
} else {
description += QString("%1,").arg(QObject::tr("has a long comment"));
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!user->qsComment().isEmpty()) { | |
| if (user->qsComment().length() <= 20) { | |
| description += QString("%1,").arg(user->qsComment()); | |
| } else { | |
| description += QString("%1,").arg(QObject::tr("has a long comment")); | |
| } | |
| const QString comment = removeHTMLTags(user->qsComment()); | |
| if (!comment.isEmpty()) { | |
| if (comment.length() <= 20) { | |
| description += QString("%1,").arg(comment); | |
| } else { | |
| description += QString("%1,").arg(QObject::tr("has a long comment")); | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/mumble/Accessibility.cpp around lines 81-86, the code appends
user->qsComment() directly (and calls the accessor multiple times) which may
contain HTML and thus should be sanitized and not re-accessed repeatedly; fetch
user->qsComment() into a local QString, call removeHTMLTags() on it, use the
stripped string for the length check and for appending to description (or fall
back to QObject::tr("has a long comment") when the stripped length > 20), and
ensure you append the sanitized value followed by the comma.
| void ImageWidget::resizeEvent(QResizeEvent *event) { | ||
| const QPixmap scaled = m_pix.scaled( | ||
| sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumWidth() : event->size().width(), | ||
| sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumHeight() : event->size().width(), | ||
| Qt::KeepAspectRatio, Qt::SmoothTransformation); | ||
| setPixmap(scaled); | ||
|
|
||
| m_sizeHint = scaled.size(); | ||
|
|
||
| QLabel::resizeEvent(event); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix axis mix-up and guard against null pixmaps in resizeEvent (prevents wrong scaling and Qt warnings).
- Height uses
event->size().width()and checks the horizontal policy for both axes. This distorts aspect ratio and ignores actual height. - When
m_pixis null,QPixmap::scaledwarns and does nothing useful. - Using only
maximumWidth/Heightfor the target size can create huge pixmaps if those maxima aren’t set (default is very large). Clamp to the current size as well.
Apply:
void ImageWidget::resizeEvent(QResizeEvent *event) {
- const QPixmap scaled = m_pix.scaled(
- sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumWidth() : event->size().width(),
- sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumHeight() : event->size().width(),
- Qt::KeepAspectRatio, Qt::SmoothTransformation);
- setPixmap(scaled);
-
- m_sizeHint = scaled.size();
+ if (m_pix.isNull()) {
+ QLabel::resizeEvent(event);
+ return;
+ }
+ const int targetW = qMin(event->size().width(), maximumWidth());
+ const int targetH = qMin(event->size().height(), maximumHeight());
+ const QPixmap scaled =
+ m_pix.scaled(targetW, targetH, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ setPixmap(scaled);
+ m_sizeHint = scaled.size();
QLabel::resizeEvent(event);
}This clamps by the widget’s current size and respects its maxima, avoiding the oversized avatar issue reported in the PR discussion while preserving aspect ratio.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void ImageWidget::resizeEvent(QResizeEvent *event) { | |
| const QPixmap scaled = m_pix.scaled( | |
| sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumWidth() : event->size().width(), | |
| sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumHeight() : event->size().width(), | |
| Qt::KeepAspectRatio, Qt::SmoothTransformation); | |
| setPixmap(scaled); | |
| m_sizeHint = scaled.size(); | |
| QLabel::resizeEvent(event); | |
| } | |
| void ImageWidget::resizeEvent(QResizeEvent *event) { | |
| // If there's no pixmap to scale, just propagate the event. | |
| if (m_pix.isNull()) { | |
| QLabel::resizeEvent(event); | |
| return; | |
| } | |
| // Clamp target dimensions to the widget's current size and its maxima. | |
| const int targetW = qMin(event->size().width(), maximumWidth()); | |
| const int targetH = qMin(event->size().height(), maximumHeight()); | |
| // Scale the pixmap correctly (respecting aspect ratio, smooth transformation). | |
| const QPixmap scaled = | |
| m_pix.scaled(targetW, targetH, Qt::KeepAspectRatio, Qt::SmoothTransformation); | |
| setPixmap(scaled); | |
| m_sizeHint = scaled.size(); | |
| QLabel::resizeEvent(event); | |
| } |
🤖 Prompt for AI Agents
In src/mumble/widgets/ImageWidget.cpp around lines 15-25, the resizeEvent mixes
axes, doesn't guard null pixmaps, and can scale to enormous sizes; fix by
returning early if m_pix.isNull(), compute targetWidth as qMin(maximumWidth(),
event->size().width()) and targetHeight as qMin(maximumHeight(),
event->size().height()) (use horizontalPolicy for width and verticalPolicy for
height where needed), call m_pix.scaled(QSize(targetWidth, targetHeight),
Qt::KeepAspectRatio, Qt::SmoothTransformation), set m_sizeHint from the
resulting pixmap, and then call QLabel::resizeEvent(event); ensure you clamp to
the widget's current/event size and maxima to avoid oversized pixmaps.

Implements #3386
This is just a work in progress and solves some things in ways I personally don't think of as too nice. Perhaps someone can skim over it and give some tips.
Also the commit is not yet cleaned up of changes done by QT editor.
Additionally would be greatly appreciated if someone could try it out and give feedback whether it matches the things that were expected.
(Does layout saving work? Because for me it does not, but it also does not work from the master branch)
Edit: just noticed it doesn't even build the server, ups :DChecks
Summary by CodeRabbit
New Features
Improvements
Localization
Chores