fix(team): prevent composer recipient overflow

This commit is contained in:
777genius 2026-05-30 18:46:21 +03:00
parent a7606032fc
commit 7be9158eb3
17 changed files with 61 additions and 22 deletions

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Reused recent cross-team request", "reusedCrossTeamRequest": "Reused recent cross-team request",
"teamOffline": "الفريق غير المباشر" "teamOffline": "غير متصل"
}, },
"revision": { "revision": {
"editing": "جارٍ تعديل الرسالة السابقة", "editing": "جارٍ تعديل الرسالة السابقة",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "সম্প্রতি ব্যবহৃত ক্রস-টেম অনুরোধ", "reusedCrossTeamRequest": "সম্প্রতি ব্যবহৃত ক্রস-টেম অনুরোধ",
"teamOffline": "অফলাইন অবস্থায় ব্যবহারের জন্য প্রস্তুত করা হচ্ছে" "teamOffline": "অফলাইন"
}, },
"revision": { "revision": {
"editing": "আগের বার্তা সম্পাদনা করা হচ্ছে", "editing": "আগের বার্তা সম্পাদনা করা হচ্ছে",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Neuer Cross-Dampf-Antrag", "reusedCrossTeamRequest": "Neuer Cross-Dampf-Antrag",
"teamOffline": "Team offline" "teamOffline": "offline"
}, },
"revision": { "revision": {
"editing": "Vorherige Nachricht wird bearbeitet", "editing": "Vorherige Nachricht wird bearbeitet",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Reused recent cross-team request", "reusedCrossTeamRequest": "Reused recent cross-team request",
"teamOffline": "Team offline" "teamOffline": "offline"
}, },
"revision": { "revision": {
"editing": "Editing previous message", "editing": "Editing previous message",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Reutilización reciente de la solicitud de equipo cruzado", "reusedCrossTeamRequest": "Reutilización reciente de la solicitud de equipo cruzado",
"teamOffline": "Team offline" "teamOffline": "sin conexión"
}, },
"revision": { "revision": {
"editing": "Editando mensaje anterior", "editing": "Editando mensaje anterior",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Réutilisée récente demande cross-team", "reusedCrossTeamRequest": "Réutilisée récente demande cross-team",
"teamOffline": "Équipe hors ligne" "teamOffline": "hors ligne"
}, },
"revision": { "revision": {
"editing": "Modification du message précédent", "editing": "Modification du message précédent",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "हाल के क्रॉस-टीम अनुरोध का पुन: उपयोग किया", "reusedCrossTeamRequest": "हाल के क्रॉस-टीम अनुरोध का पुन: उपयोग किया",
"teamOffline": "टीम ऑफलाइन" "teamOffline": "ऑफलाइन"
}, },
"revision": { "revision": {
"editing": "पिछला संदेश संपादित हो रहा है", "editing": "पिछला संदेश संपादित हो रहा है",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Mengulang permintaan tim-cross- baru-baru ini", "reusedCrossTeamRequest": "Mengulang permintaan tim-cross- baru-baru ini",
"teamOffline": "Tim luring" "teamOffline": "offline"
}, },
"revision": { "revision": {
"editing": "Mengedit pesan sebelumnya", "editing": "Mengedit pesan sebelumnya",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "最近のクロスチームリクエストを再利用", "reusedCrossTeamRequest": "最近のクロスチームリクエストを再利用",
"teamOffline": "オフラインチーム" "teamOffline": "オフライン"
}, },
"revision": { "revision": {
"editing": "前のメッセージを編集中", "editing": "前のメッセージを編集中",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "최근 Cross-team 요청 사용", "reusedCrossTeamRequest": "최근 Cross-team 요청 사용",
"teamOffline": "오프라인" "teamOffline": "오프라인"
}, },
"revision": { "revision": {
"editing": "이전 메시지 편집 중", "editing": "이전 메시지 편집 중",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Reutilizar o pedido de equipa cruzada recente", "reusedCrossTeamRequest": "Reutilizar o pedido de equipa cruzada recente",
"teamOffline": "Equipa offline" "teamOffline": "offline"
}, },
"revision": { "revision": {
"editing": "A editar a mensagem anterior", "editing": "A editar a mensagem anterior",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "Повторно использован недавний cross-team request", "reusedCrossTeamRequest": "Повторно использован недавний cross-team request",
"teamOffline": "Команда offline" "teamOffline": "оффлайн"
}, },
"revision": { "revision": {
"editing": "Редактируется предыдущее сообщение", "editing": "Редактируется предыдущее сообщение",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "حالیہ صلیبی درخواست استعمال کریں", "reusedCrossTeamRequest": "حالیہ صلیبی درخواست استعمال کریں",
"teamOffline": "گروپ" "teamOffline": "آف لائن"
}, },
"revision": { "revision": {
"editing": "پچھلا پیغام ترمیم ہو رہا ہے", "editing": "پچھلا پیغام ترمیم ہو رہا ہے",

View file

@ -1485,7 +1485,7 @@
}, },
"status": { "status": {
"reusedCrossTeamRequest": "重新使用最近的跨小组请求", "reusedCrossTeamRequest": "重新使用最近的跨小组请求",
"teamOffline": "团队离线" "teamOffline": "离线"
}, },
"revision": { "revision": {
"editing": "正在编辑上一条消息", "editing": "正在编辑上一条消息",

View file

@ -4236,7 +4236,7 @@ export default interface Resources {
}; };
status: { status: {
reusedCrossTeamRequest: 'Reused recent cross-team request'; reusedCrossTeamRequest: 'Reused recent cross-team request';
teamOffline: 'Team offline'; teamOffline: 'offline';
}; };
teamSelector: { teamSelector: {
current: 'current'; current: 'current';

View file

@ -894,7 +894,7 @@ export const MessageComposer = ({
isCompactLayout ? 'space-y-1.5' : 'space-y-2' isCompactLayout ? 'space-y-1.5' : 'space-y-2'
)} )}
> >
<div className="flex items-center gap-2"> <div className="flex min-w-0 items-center gap-2">
{showAttachmentControl ? ( {showAttachmentControl ? (
<> <>
<input <input
@ -930,9 +930,12 @@ export const MessageComposer = ({
</> </>
) : null} ) : null}
<div className="ml-auto flex shrink-0 items-center gap-2"> <div className="ml-auto flex min-w-0 max-w-full items-center justify-end gap-2">
{!isTeamAlive && !isLaunchBlocking && ( {!isTeamAlive && !isLaunchBlocking && (
<span className="text-[10px]" style={{ color: 'var(--warning-text)' }}> <span
className="shrink-0 whitespace-nowrap text-[10px]"
style={{ color: 'var(--warning-text)' }}
>
{t('messageComposer.status.teamOffline')} {t('messageComposer.status.teamOffline')}
</span> </span>
)} )}
@ -940,7 +943,7 @@ export const MessageComposer = ({
{/* Combined team + member selector */} {/* Combined team + member selector */}
<div <div
className={cn( className={cn(
'mr-[15px] inline-flex items-center border text-xs transition-colors', 'mr-[15px] inline-flex min-w-0 max-w-[calc(100%_-_15px)] items-center overflow-hidden border text-xs transition-colors',
shouldDockRecipientSelector shouldDockRecipientSelector
? 'relative z-[1] -mb-px overflow-hidden rounded-b-none rounded-t-[1.35rem] border-b-0 bg-[var(--color-surface-raised)]' ? 'relative z-[1] -mb-px overflow-hidden rounded-b-none rounded-t-[1.35rem] border-b-0 bg-[var(--color-surface-raised)]'
: 'rounded-full', : 'rounded-full',
@ -952,7 +955,7 @@ export const MessageComposer = ({
<button <button
type="button" type="button"
className={cn( className={cn(
'inline-flex items-center gap-1.5 border-r border-r-[var(--color-border)] px-2.5 py-1 text-xs transition-colors', 'inline-flex min-w-0 max-w-[160px] items-center gap-1.5 border-r border-r-[var(--color-border)] px-2.5 py-1 text-xs transition-colors',
shouldDockRecipientSelector shouldDockRecipientSelector
? 'rounded-bl-none rounded-tl-[1.35rem]' ? 'rounded-bl-none rounded-tl-[1.35rem]'
: 'rounded-l-full', : 'rounded-l-full',
@ -988,7 +991,7 @@ export const MessageComposer = ({
style={{ backgroundColor: currentTeamColor }} style={{ backgroundColor: currentTeamColor }}
/> />
) : null} ) : null}
<span className="text-[var(--color-text-secondary)]"> <span className="min-w-0 truncate text-[var(--color-text-secondary)]">
{t('messageComposer.teamSelector.thisTeam')} {t('messageComposer.teamSelector.thisTeam')}
</span> </span>
</> </>
@ -1111,7 +1114,7 @@ export const MessageComposer = ({
<button <button
type="button" type="button"
className={cn( className={cn(
'inline-flex items-center gap-1.5 px-2.5 py-1 text-xs transition-colors', 'inline-flex min-w-0 max-w-[150px] items-center gap-1.5 px-2.5 py-1 text-xs transition-colors',
shouldDockRecipientSelector shouldDockRecipientSelector
? 'rounded-br-none rounded-tr-[1.35rem]' ? 'rounded-br-none rounded-tr-[1.35rem]'
: 'rounded-r-full', : 'rounded-r-full',

View file

@ -1552,10 +1552,34 @@ a[href],
.message-composer-orbit-path, .message-composer-orbit-path,
.message-composer-orbit-glow { .message-composer-orbit-glow {
stroke-dasharray: 9 91; stroke-dasharray: 9 91;
animation: message-composer-orbit-dash 9.6s linear infinite;
stroke-linecap: butt; stroke-linecap: butt;
stroke-linejoin: round; stroke-linejoin: round;
} }
.message-composer-orbit-path-secondary,
.message-composer-orbit-glow-secondary {
animation-name: message-composer-orbit-dash-secondary;
}
@keyframes message-composer-orbit-dash {
from {
stroke-dashoffset: 0;
}
to {
stroke-dashoffset: -100;
}
}
@keyframes message-composer-orbit-dash-secondary {
from {
stroke-dashoffset: 50;
}
to {
stroke-dashoffset: -50;
}
}
.message-composer-orbit-path { .message-composer-orbit-path {
stroke-width: 1.35px; stroke-width: 1.35px;
stroke: var(--message-composer-orbit-stroke); stroke: var(--message-composer-orbit-stroke);
@ -1576,6 +1600,18 @@ a[href],
opacity: 0.36; opacity: 0.36;
} }
@media (prefers-reduced-motion: reduce) {
.message-composer-orbit-path,
.message-composer-orbit-glow {
animation: none;
}
.message-composer-orbit-path-secondary,
.message-composer-orbit-glow-secondary {
stroke-dashoffset: 50;
}
}
:root.light .message-composer-shell { :root.light .message-composer-shell {
background-color: #dfdbd4; background-color: #dfdbd4;
box-shadow: box-shadow: