From 4240202a139bfb6d367a05e18b9d6c228e44cecd Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Wed, 3 Dec 2025 14:37:43 -0300 Subject: [PATCH 1/6] feat(ABAC): Add icons (#6758) --- android/app/src/main/assets/fonts/custom.ttf | Bin 59536 -> 60564 bytes app/containers/CustomIcon/mappedIcons.js | 2 + app/containers/CustomIcon/selection.json | 2 +- .../RoomHeader/RoomHeader.stories.tsx | 2 + app/containers/RoomHeader/RoomHeader.tsx | 8 +- .../__snapshots__/RoomHeader.test.tsx.snap | 286 +++- app/containers/RoomHeader/index.tsx | 7 +- app/containers/RoomItem/IconOrAvatar.tsx | 4 +- app/containers/RoomItem/RoomItem.stories.tsx | 2 + app/containers/RoomItem/RoomItem.tsx | 5 +- app/containers/RoomItem/TypeIcon.tsx | 27 +- .../__snapshots__/RoomItem.test.tsx.snap | 1262 ++++++++++++++++- app/containers/RoomItem/index.tsx | 1 + app/containers/RoomItem/interfaces.ts | 3 + .../RoomTypeIcon/RoomTypeIcon.stories.tsx | 2 + .../__snapshots__/RoomTypeIcon.test.tsx.snap | 62 + app/containers/RoomTypeIcon/index.tsx | 9 +- app/definitions/ISubscription.ts | 1 + app/lib/database/model/Subscription.js | 5 +- app/lib/database/model/migrations.js | 9 + app/lib/database/schema/app.js | 5 +- .../helpers/mergeSubscriptionsRooms.ts | 1 + app/views/RoomActionsView/index.tsx | 1 + .../components/RoomInfoViewTitle.tsx | 1 + app/views/RoomView/index.tsx | 1 + ios/custom.ttf | Bin 59536 -> 60564 bytes 26 files changed, 1662 insertions(+), 46 deletions(-) diff --git a/android/app/src/main/assets/fonts/custom.ttf b/android/app/src/main/assets/fonts/custom.ttf index 410ec49c02906ac08dad8828039e339c8a15c963..b0758f2fa60ec7d33ab136418ed1aa939022731b 100644 GIT binary patch delta 1263 zcmZuxO>7%g5T1E&f8N^JeO~W+O^DmtyYWv5CH`B-G(R9N90Do|6{n!ol#&S5X-X3* zaHw)fdm8uhe}wSxu6!QNR_Gr34(Ghssu`yUDFCE*1VlJ^Jc#JX5{zY z{+7S{J?{YmKoT~AL-pkI6Lp!^J@QD=qD zs9(MIJJ}lmKW;9c?Yw-v_tJX+Ki#GC)-pNtua$2A_Nru$E_c^9KG>lh?41JOAD%mZ z=JC#*n~!b*{6bE=-tBCx!d)x^{Cb@n`IS!h>~{z4kH{uKd}H;oW)48C13ZoNZMGlA{4JtsP|ek*esQ+evNXgrCN*=l%hC^ zaglM1Q3-y6c0qX-?~@`r6rz|U&|1adTTO9qfDaQQ0rdC)doiPUPRa|73&@iA!?mSm7>;g-5qlrr{bvYc!sIW z&LvHoF{UI1QyAk+5vp(!2Y)b?Ye`iV3i;?nBqwqqigjxCWa zWE{E1g%rq96;e;Qh9GMI?NG{}R^AetrJ*cHRj3(%NcvK6m2=e|3W9QLIK%pe(XQn4 zrh}Mp6O?;!85tsu6pOu)q$`X}A~oiPb93P#RNC!Iv`oh_Y2j6WahR*ZSP6m^L#TXs z5wB^e={gD~n8q~Ml;sT7Ti1!56Eh=PDk=&hC(>lZ{W=K>xP<79rINNr)u*X9>>-Mr zeJQH8o<3%fo0vrzq&ZC}9zx`$j2Cs(2$9iVV+uENX_Xulp)0i^8*#Q(u4T){XyRdO zsnQO0ige7SXx6qt-=D35T^t!H>Y6p2Fy&kr&gI)r#m!dQPsZI+$9-v8^HV1l(&>d0 zQ}dQ3f!)6$GjNh_Mcq4s(PaqiLP#pJEt|)C|MSNwzJ2BD9mvTZiz8>FRGjkU|i64=69K#(y}+&l5dSTd#hxyC|pcKvIdWKRqat po}q!>9=$b*w|5tAz0bFw`$2rVcMXRw%wOooxwkRcy|Mop{ssNM!|DJ4 delta 272 zcmbPolX=2L=6VK31_lOhh6V;^1_S?KeItG$b`hY+9w1Ig&P^;354)Vrz`!U2<98I7#Qw%WTYmhXh-+~`45583}zWX0ro>Ir+|D5AYUaT zx1?g>0+7_h7zPIBB{})YmWeGryUsB%JOv6eUdc_YC}8-;sK~(Z>$5Um4^NAl6!VJ~N)*<|_j?3rHQq n6PZ?^aS(d4%u{p5mzzVLE@9sE@(Lpd*zYeH ( } /> } /> } /> + } /> + } /> ); diff --git a/app/containers/RoomHeader/RoomHeader.tsx b/app/containers/RoomHeader/RoomHeader.tsx index ec65eb792ea..bd2a95d89d5 100644 --- a/app/containers/RoomHeader/RoomHeader.tsx +++ b/app/containers/RoomHeader/RoomHeader.tsx @@ -7,7 +7,7 @@ import I18n from '../../i18n'; import sharedStyles from '../../views/Styles'; import { MarkdownPreview } from '../markdown'; import RoomTypeIcon from '../RoomTypeIcon'; -import { type TUserStatus, type IOmnichannelSource } from '../../definitions'; +import { type TUserStatus, type IOmnichannelSource, type ISubscription } from '../../definitions'; import { useTheme } from '../../theme'; import { useAppSelector } from '../../lib/hooks/useAppSelector'; import useStatusAccessibilityLabel from '../../lib/hooks/useStatusAccessibilityLabel'; @@ -80,6 +80,7 @@ interface IRoomHeader { sourceType?: IOmnichannelSource; disabled?: boolean; rightButtonsWidth?: number; + abacAttributes?: ISubscription['abacAttributes']; } const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoomHeaderSubTitle) => { @@ -148,7 +149,8 @@ const Header = React.memo( testID, usersTyping = [], sourceType, - disabled + disabled, + abacAttributes }: IRoomHeader) => { const statusAccessibilityLabel = useStatusAccessibilityLabel({ isGroupChat, @@ -182,6 +184,7 @@ const Header = React.memo( isGroupChat={isGroupChat} status={status} teamMain={teamMain} + abacAttributes={abacAttributes} /> {parentTitle} @@ -208,6 +211,7 @@ const Header = React.memo( status={status} teamMain={teamMain} sourceType={sourceType} + abacAttributes={abacAttributes} /> )} diff --git a/app/containers/RoomHeader/__snapshots__/RoomHeader.test.tsx.snap b/app/containers/RoomHeader/__snapshots__/RoomHeader.test.tsx.snap index f75b0a2470e..089fa4625c8 100644 --- a/app/containers/RoomHeader/__snapshots__/RoomHeader.test.tsx.snap +++ b/app/containers/RoomHeader/__snapshots__/RoomHeader.test.tsx.snap @@ -1575,6 +1575,266 @@ exports[`Story Snapshots: Icons should match snapshot 1`] = ` , + + + + + + +  + + + classified + + + + + + , + + + + + + +  + + + classified + + + + + + , ] `; @@ -1611,7 +1871,7 @@ exports[`Story Snapshots: Themes should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={13} + handlerTag={15} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -1774,7 +2034,7 @@ exports[`Story Snapshots: Themes should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={14} + handlerTag={16} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -1937,7 +2197,7 @@ exports[`Story Snapshots: Themes should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={15} + handlerTag={17} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -2105,7 +2365,7 @@ exports[`Story Snapshots: Thread should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={16} + handlerTag={18} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -2280,7 +2540,7 @@ preview delayLongPress={600} enabled={true} exclusive={true} - handlerTag={17} + handlerTag={19} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -2460,7 +2720,7 @@ exports[`Story Snapshots: TitleSubtitle should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={18} + handlerTag={20} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -2590,7 +2850,7 @@ exports[`Story Snapshots: TitleSubtitle should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={19} + handlerTag={21} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -2720,7 +2980,7 @@ exports[`Story Snapshots: TitleSubtitle should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={20} + handlerTag={22} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -2883,7 +3143,7 @@ exports[`Story Snapshots: TitleSubtitle should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={21} + handlerTag={23} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -3046,7 +3306,7 @@ exports[`Story Snapshots: TitleSubtitle should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={22} + handlerTag={24} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -3215,7 +3475,7 @@ exports[`Story Snapshots: Typing should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={23} + handlerTag={25} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -3378,7 +3638,7 @@ exports[`Story Snapshots: Typing should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={24} + handlerTag={26} handlerType="NativeViewGestureHandler" hitSlop={ { @@ -3541,7 +3801,7 @@ exports[`Story Snapshots: Typing should match snapshot 1`] = ` delayLongPress={600} enabled={true} exclusive={true} - handlerTag={25} + handlerTag={27} handlerType="NativeViewGestureHandler" hitSlop={ { diff --git a/app/containers/RoomHeader/index.tsx b/app/containers/RoomHeader/index.tsx index 838c5eb62cc..50a3df02f9d 100644 --- a/app/containers/RoomHeader/index.tsx +++ b/app/containers/RoomHeader/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { shallowEqual, useSelector } from 'react-redux'; -import { type IApplicationState, type TUserStatus, type IOmnichannelSource, type IVisitor } from '../../definitions'; +import type { IApplicationState, TUserStatus, IOmnichannelSource, IVisitor, ISubscription } from '../../definitions'; import I18n from '../../i18n'; import RoomHeader from './RoomHeader'; import { useResponsiveLayout } from '../../lib/hooks/useResponsiveLayout/useResponsiveLayout'; @@ -21,6 +21,7 @@ interface IRoomHeaderContainerProps { sourceType?: IOmnichannelSource; visitor?: IVisitor; disabled?: boolean; + abacAttributes?: ISubscription['abacAttributes']; } const RoomHeaderContainer = React.memo( @@ -38,7 +39,8 @@ const RoomHeaderContainer = React.memo( type, sourceType, visitor, - disabled + disabled, + abacAttributes }: IRoomHeaderContainerProps) => { let subtitle: string | undefined; let statusVisitor: TUserStatus | undefined; @@ -89,6 +91,7 @@ const RoomHeaderContainer = React.memo( onPress={onPress} sourceType={sourceType} disabled={disabled} + abacAttributes={abacAttributes} /> ); } diff --git a/app/containers/RoomItem/IconOrAvatar.tsx b/app/containers/RoomItem/IconOrAvatar.tsx index 5a5c6de9ad5..59d054864b4 100644 --- a/app/containers/RoomItem/IconOrAvatar.tsx +++ b/app/containers/RoomItem/IconOrAvatar.tsx @@ -20,7 +20,8 @@ const IconOrAvatar = ({ teamMain, showLastMessage, displayMode, - sourceType + sourceType, + abacAttributes }: IIconOrAvatar): React.ReactElement | null => { const { rowHeight } = useResponsiveLayout(); @@ -43,6 +44,7 @@ const IconOrAvatar = ({ size={24} style={{ marginRight: 12 }} sourceType={sourceType} + abacAttributes={abacAttributes} /> ); diff --git a/app/containers/RoomItem/RoomItem.stories.tsx b/app/containers/RoomItem/RoomItem.stories.tsx index 962de2ab91d..ccfcf93893b 100644 --- a/app/containers/RoomItem/RoomItem.stories.tsx +++ b/app/containers/RoomItem/RoomItem.stories.tsx @@ -71,6 +71,8 @@ export const Type = () => ( + + ); diff --git a/app/containers/RoomItem/RoomItem.tsx b/app/containers/RoomItem/RoomItem.tsx index 3b6454fbbc6..75f302422b1 100644 --- a/app/containers/RoomItem/RoomItem.tsx +++ b/app/containers/RoomItem/RoomItem.tsx @@ -53,7 +53,8 @@ const RoomItem = ({ displayMode, sourceType, hideMentionStatus, - accessibilityDate + accessibilityDate, + abacAttributes }: IRoomItemProps) => { 'use memo'; @@ -112,6 +113,7 @@ const RoomItem = ({ isGroupChat={isGroupChat} teamMain={teamMain} sourceType={sourceType} + abacAttributes={abacAttributes} /> ) : null} @@ -153,6 +155,7 @@ const RoomItem = ({ size={22} style={{ marginRight: 8 }} sourceType={sourceType} + abacAttributes={abacAttributes} /> <Title name={name} hideUnreadStatus={hideUnreadStatus} alert={alert} /> {autoJoin ? <Tag name={I18n.t('Auto-join')} /> : null} diff --git a/app/containers/RoomItem/TypeIcon.tsx b/app/containers/RoomItem/TypeIcon.tsx index ad14a7037f0..b2556a8770c 100644 --- a/app/containers/RoomItem/TypeIcon.tsx +++ b/app/containers/RoomItem/TypeIcon.tsx @@ -3,17 +3,20 @@ import React from 'react'; import RoomTypeIcon from '../RoomTypeIcon'; import { type ITypeIconProps } from './interfaces'; -const TypeIcon = React.memo(({ userId, type, prid, status, isGroupChat, teamMain, size, style, sourceType }: ITypeIconProps) => ( - <RoomTypeIcon - userId={userId} - type={prid ? 'discussion' : type} - isGroupChat={isGroupChat} - status={status} - teamMain={teamMain} - size={size} - style={style} - sourceType={sourceType} - /> -)); +const TypeIcon = React.memo( + ({ userId, type, prid, status, isGroupChat, teamMain, size, style, sourceType, abacAttributes }: ITypeIconProps) => ( + <RoomTypeIcon + userId={userId} + type={prid ? 'discussion' : type} + isGroupChat={isGroupChat} + status={status} + teamMain={teamMain} + size={size} + style={style} + sourceType={sourceType} + abacAttributes={abacAttributes} + /> + ) +); export default TypeIcon; diff --git a/app/containers/RoomItem/__snapshots__/RoomItem.test.tsx.snap b/app/containers/RoomItem/__snapshots__/RoomItem.test.tsx.snap index a57f8ad2e8e..9e8141dec08 100644 --- a/app/containers/RoomItem/__snapshots__/RoomItem.test.tsx.snap +++ b/app/containers/RoomItem/__snapshots__/RoomItem.test.tsx.snap @@ -32397,6 +32397,1252 @@ exports[`Story Snapshots: Type should match snapshot 1`] = ` width={48} /> </View> + <View + style={ + [ + { + "borderBottomWidth": 0.5, + "flex": 1, + "paddingRight": 14, + "paddingVertical": 10, + }, + { + "borderColor": "#CBCED1", + }, + ] + } + > + <View + style={ + [ + { + "alignItems": "center", + "flexDirection": "row", + "justifyContent": "center", + "width": "100%", + }, + { + "flex": 1, + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#1F2329", + "fontSize": 22, + }, + [ + { + "lineHeight": 22, + }, + [ + { + "marginRight": 4, + }, + { + "marginRight": 8, + }, + ], + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + ellipsizeMode="tail" + numberOfLines={1} + style={ + [ + { + "backgroundColor": "transparent", + "flex": 1, + "fontFamily": "Inter", + "fontSize": 17, + "fontWeight": "500", + "textAlign": "left", + }, + undefined, + { + "color": "#1F2329", + }, + ] + } + > + rocket.cat + </Text> + <View + style={ + { + "alignItems": "flex-end", + } + } + > + <Text + ellipsizeMode="tail" + numberOfLines={1} + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 13, + "fontWeight": "400", + "marginLeft": 4, + "textAlign": "left", + }, + { + "color": "#2F343D", + }, + undefined, + ] + } + > + 10:00 + </Text> + </View> + </View> + </View> + </View> + </View> + </RNGestureHandlerButton> + </View> + </View>, + <View + collapsable={false} + > + <View + pointerEvents="box-none" + style={ + [ + { + "left": 0, + "position": "absolute", + "right": 0, + }, + { + "flexDirection": "row", + "left": 0, + "position": "absolute", + "right": 0, + }, + ] + } + > + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "right": 0, + "top": 0, + }, + { + "backgroundColor": "#1D74F5", + "right": "100%", + "width": 1500, + }, + { + "height": 75, + }, + { + "transform": [ + { + "translateX": 0, + }, + ], + }, + ] + } + > + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "right": 0, + "top": 0, + }, + { + "height": 75, + }, + ] + } + > + <RNGestureHandlerButton + accessibilityLabel="Mark read" + accessible={true} + activeOpacity={0.105} + collapsable={false} + delayLongPress={600} + handlerTag={287} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + style={ + [ + { + "alignItems": "center", + "height": "100%", + "justifyContent": "center", + "width": 80, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="black" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "black", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#FFFFFF", + "fontSize": 28, + }, + [ + { + "lineHeight": 28, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + </RNGestureHandlerButton> + </View> + </View> + </View> + <View + pointerEvents="box-none" + style={ + [ + { + "flexDirection": "row", + "left": 0, + "position": "absolute", + "right": 0, + }, + { + "height": 75, + }, + ] + } + > + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "top": 0, + }, + { + "backgroundColor": "#8E6300", + "left": "100%", + "width": 750, + }, + { + "height": 75, + }, + { + "transform": [ + { + "translateX": 0, + }, + ], + }, + ] + } + > + <RNGestureHandlerButton + accessibilityLabel="Favorite" + accessible={true} + activeOpacity={0.105} + collapsable={false} + delayLongPress={600} + handlerTag={288} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + style={ + [ + { + "alignItems": "center", + "backgroundColor": "#8E6300", + "height": "100%", + "justifyContent": "center", + "width": 80, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="black" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "black", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#FFFFFF", + "fontSize": 28, + }, + [ + { + "lineHeight": 28, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + </RNGestureHandlerButton> + </View> + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "top": 0, + }, + { + "backgroundColor": "#9EA2A8", + "left": "100%", + "width": 1500, + }, + { + "height": 75, + }, + { + "transform": [ + { + "translateX": 80, + }, + ], + }, + ] + } + > + <RNGestureHandlerButton + accessibilityLabel="Hide" + accessible={true} + activeOpacity={0.105} + collapsable={false} + delayLongPress={600} + handlerTag={289} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + style={ + [ + { + "alignItems": "center", + "backgroundColor": "#9EA2A8", + "height": "100%", + "justifyContent": "center", + "width": 80, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="black" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "black", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#FFFFFF", + "fontSize": 28, + }, + [ + { + "lineHeight": 28, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + </RNGestureHandlerButton> + </View> + </View> + <View + style={ + { + "transform": [ + { + "translateX": 0, + }, + ], + } + } + > + <RNGestureHandlerButton + activeOpacity={1} + collapsable={false} + delayLongPress={600} + handlerTag={290} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + rippleColor="#E4E7EA" + style={ + [ + { + "backgroundColor": "#FFFFFF", + "borderRadius": undefined, + "margin": undefined, + "marginBottom": undefined, + "marginEnd": undefined, + "marginHorizontal": undefined, + "marginLeft": undefined, + "marginRight": undefined, + "marginStart": undefined, + "marginTop": undefined, + "marginVertical": undefined, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="#E4E7EA" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "#E4E7EA", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <View + style={{}} + > + <View + accessibilityLabel="rocket.cat. private team. undefined. " + accessibilityRole="button" + accessible={true} + style={ + [ + { + "alignItems": "center", + "flexDirection": "row", + "paddingLeft": 14, + }, + { + "height": 75, + }, + ] + } + > + <View + accessibilityLabel="rocket.cat's avatar" + accessible={true} + style={ + [ + { + "borderRadius": 4, + "height": 48, + "width": 48, + }, + { + "marginRight": 10, + }, + ] + } + testID="avatar" + > + <ViewManagerAdapter_ExpoImage + borderRadius={4} + containerViewRef={"[React.ref]"} + contentFit="cover" + contentPosition={ + { + "left": "50%", + "top": "50%", + } + } + height={48} + nativeViewRef={"[React.ref]"} + onError={[Function]} + onLoad={[Function]} + onLoadStart={[Function]} + onProgress={[Function]} + placeholder={[]} + priority="high" + source={ + [ + { + "headers": { + "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)", + }, + "uri": "https://open.rocket.chat/avatar/@rocket.cat?format=png&size=96", + }, + ] + } + style={ + { + "borderRadius": 4, + "height": 48, + "width": 48, + } + } + transition={null} + width={48} + /> + </View> + <View + style={ + [ + { + "borderBottomWidth": 0.5, + "flex": 1, + "paddingRight": 14, + "paddingVertical": 10, + }, + { + "borderColor": "#CBCED1", + }, + ] + } + > + <View + style={ + [ + { + "alignItems": "center", + "flexDirection": "row", + "justifyContent": "center", + "width": "100%", + }, + { + "flex": 1, + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#1F2329", + "fontSize": 22, + }, + [ + { + "lineHeight": 22, + }, + [ + { + "marginRight": 4, + }, + { + "marginRight": 8, + }, + ], + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + ellipsizeMode="tail" + numberOfLines={1} + style={ + [ + { + "backgroundColor": "transparent", + "flex": 1, + "fontFamily": "Inter", + "fontSize": 17, + "fontWeight": "500", + "textAlign": "left", + }, + undefined, + { + "color": "#1F2329", + }, + ] + } + > + rocket.cat + </Text> + <View + style={ + { + "alignItems": "flex-end", + } + } + > + <Text + ellipsizeMode="tail" + numberOfLines={1} + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 13, + "fontWeight": "400", + "marginLeft": 4, + "textAlign": "left", + }, + { + "color": "#2F343D", + }, + undefined, + ] + } + > + 10:00 + </Text> + </View> + </View> + </View> + </View> + </View> + </RNGestureHandlerButton> + </View> + </View>, + <View + collapsable={false} + > + <View + pointerEvents="box-none" + style={ + [ + { + "left": 0, + "position": "absolute", + "right": 0, + }, + { + "flexDirection": "row", + "left": 0, + "position": "absolute", + "right": 0, + }, + ] + } + > + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "right": 0, + "top": 0, + }, + { + "backgroundColor": "#1D74F5", + "right": "100%", + "width": 1500, + }, + { + "height": 75, + }, + { + "transform": [ + { + "translateX": 0, + }, + ], + }, + ] + } + > + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "right": 0, + "top": 0, + }, + { + "height": 75, + }, + ] + } + > + <RNGestureHandlerButton + accessibilityLabel="Mark read" + accessible={true} + activeOpacity={0.105} + collapsable={false} + delayLongPress={600} + handlerTag={291} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + style={ + [ + { + "alignItems": "center", + "height": "100%", + "justifyContent": "center", + "width": 80, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="black" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "black", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#FFFFFF", + "fontSize": 28, + }, + [ + { + "lineHeight": 28, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + </RNGestureHandlerButton> + </View> + </View> + </View> + <View + pointerEvents="box-none" + style={ + [ + { + "flexDirection": "row", + "left": 0, + "position": "absolute", + "right": 0, + }, + { + "height": 75, + }, + ] + } + > + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "top": 0, + }, + { + "backgroundColor": "#8E6300", + "left": "100%", + "width": 750, + }, + { + "height": 75, + }, + { + "transform": [ + { + "translateX": 0, + }, + ], + }, + ] + } + > + <RNGestureHandlerButton + accessibilityLabel="Favorite" + accessible={true} + activeOpacity={0.105} + collapsable={false} + delayLongPress={600} + handlerTag={292} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + style={ + [ + { + "alignItems": "center", + "backgroundColor": "#8E6300", + "height": "100%", + "justifyContent": "center", + "width": 80, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="black" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "black", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#FFFFFF", + "fontSize": 28, + }, + [ + { + "lineHeight": 28, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + </RNGestureHandlerButton> + </View> + <View + style={ + [ + { + "justifyContent": "center", + "position": "absolute", + "top": 0, + }, + { + "backgroundColor": "#9EA2A8", + "left": "100%", + "width": 1500, + }, + { + "height": 75, + }, + { + "transform": [ + { + "translateX": 80, + }, + ], + }, + ] + } + > + <RNGestureHandlerButton + accessibilityLabel="Hide" + accessible={true} + activeOpacity={0.105} + collapsable={false} + delayLongPress={600} + handlerTag={293} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + style={ + [ + { + "alignItems": "center", + "backgroundColor": "#9EA2A8", + "height": "100%", + "justifyContent": "center", + "width": 80, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="black" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "black", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#FFFFFF", + "fontSize": 28, + }, + [ + { + "lineHeight": 28, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + </RNGestureHandlerButton> + </View> + </View> + <View + style={ + { + "transform": [ + { + "translateX": 0, + }, + ], + } + } + > + <RNGestureHandlerButton + activeOpacity={1} + collapsable={false} + delayLongPress={600} + handlerTag={294} + handlerType="NativeViewGestureHandler" + innerRef={null} + onActiveStateChange={[Function]} + onGestureHandlerEvent={[Function]} + onGestureHandlerStateChange={[Function]} + onPress={[Function]} + rippleColor="#E4E7EA" + style={ + [ + { + "backgroundColor": "#FFFFFF", + "borderRadius": undefined, + "margin": undefined, + "marginBottom": undefined, + "marginEnd": undefined, + "marginHorizontal": undefined, + "marginLeft": undefined, + "marginRight": undefined, + "marginStart": undefined, + "marginTop": undefined, + "marginVertical": undefined, + }, + { + "cursor": undefined, + }, + ] + } + underlayColor="#E4E7EA" + > + <View + collapsable={false} + style={ + { + "backgroundColor": "#E4E7EA", + "borderBottomLeftRadius": undefined, + "borderBottomRightRadius": undefined, + "borderRadius": undefined, + "borderTopLeftRadius": undefined, + "borderTopRightRadius": undefined, + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + } + } + /> + <View + style={{}} + > + <View + accessibilityLabel="rocket.cat. private channel. undefined. " + accessibilityRole="button" + accessible={true} + style={ + [ + { + "alignItems": "center", + "flexDirection": "row", + "paddingLeft": 14, + }, + { + "height": 75, + }, + ] + } + > + <View + accessibilityLabel="rocket.cat's avatar" + accessible={true} + style={ + [ + { + "borderRadius": 4, + "height": 48, + "width": 48, + }, + { + "marginRight": 10, + }, + ] + } + testID="avatar" + > + <ViewManagerAdapter_ExpoImage + borderRadius={4} + containerViewRef={"[React.ref]"} + contentFit="cover" + contentPosition={ + { + "left": "50%", + "top": "50%", + } + } + height={48} + nativeViewRef={"[React.ref]"} + onError={[Function]} + onLoad={[Function]} + onLoadStart={[Function]} + onProgress={[Function]} + placeholder={[]} + priority="high" + source={ + [ + { + "headers": { + "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)", + }, + "uri": "https://open.rocket.chat/avatar/@rocket.cat?format=png&size=96", + }, + ] + } + style={ + { + "borderRadius": 4, + "height": 48, + "width": 48, + } + } + transition={null} + width={48} + /> + </View> <View style={ [ @@ -32593,7 +33839,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={0.105} collapsable={false} delayLongPress={600} - handlerTag={301} + handlerTag={313} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} @@ -32712,7 +33958,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={0.105} collapsable={false} delayLongPress={600} - handlerTag={302} + handlerTag={314} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} @@ -32814,7 +34060,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={0.105} collapsable={false} delayLongPress={600} - handlerTag={303} + handlerTag={315} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} @@ -32900,7 +34146,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={1} collapsable={false} delayLongPress={600} - handlerTag={304} + handlerTag={316} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} @@ -33223,7 +34469,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={0.105} collapsable={false} delayLongPress={600} - handlerTag={305} + handlerTag={317} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} @@ -33342,7 +34588,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={0.105} collapsable={false} delayLongPress={600} - handlerTag={306} + handlerTag={318} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} @@ -33444,7 +34690,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={0.105} collapsable={false} delayLongPress={600} - handlerTag={307} + handlerTag={319} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} @@ -33530,7 +34776,7 @@ exports[`Story Snapshots: User should match snapshot 1`] = ` activeOpacity={1} collapsable={false} delayLongPress={600} - handlerTag={308} + handlerTag={320} handlerType="NativeViewGestureHandler" innerRef={null} onActiveStateChange={[Function]} diff --git a/app/containers/RoomItem/index.tsx b/app/containers/RoomItem/index.tsx index dd135367976..4509becff28 100644 --- a/app/containers/RoomItem/index.tsx +++ b/app/containers/RoomItem/index.tsx @@ -94,6 +94,7 @@ const RoomItemContainer = React.memo( displayMode={displayMode} status={item.t === 'l' ? item?.visitor?.status : null} sourceType={item.t === 'l' ? item.source : null} + abacAttributes={item.abacAttributes} /> ); }, diff --git a/app/containers/RoomItem/interfaces.ts b/app/containers/RoomItem/interfaces.ts index fc26c2663cf..ba1641b6a08 100644 --- a/app/containers/RoomItem/interfaces.ts +++ b/app/containers/RoomItem/interfaces.ts @@ -67,6 +67,7 @@ export interface ITypeIconProps { size?: number; style?: object; sourceType: IOmnichannelSource; + abacAttributes?: ISubscription['abacAttributes']; } interface IRoomItemTouchables { @@ -124,6 +125,7 @@ export interface IRoomItemProps extends IBaseRoomItem { sourceType: IOmnichannelSource; hideMentionStatus?: boolean; accessibilityDate: string; + abacAttributes?: ISubscription['abacAttributes']; } export interface ILastMessageProps { @@ -161,6 +163,7 @@ export interface IIconOrAvatar { teamMain: boolean; showLastMessage: boolean; sourceType: IOmnichannelSource; + abacAttributes?: ISubscription['abacAttributes']; } export interface IRoomItem extends ISubscription { diff --git a/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx b/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx index 02307ec8c2b..9181c98fc57 100644 --- a/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx +++ b/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx @@ -18,6 +18,8 @@ export const All = () => ( <RoomTypeIcon size={30} type='p' teamMain /> <RoomTypeIcon size={30} type='discussion' /> <RoomTypeIcon size={30} type='l' status='away' sourceType={{ type: OmnichannelSourceType.SMS }} /> + <RoomTypeIcon size={30} type='p' abacAttributes={['Classified']} /> + <RoomTypeIcon size={30} type='p' abacAttributes={['Classified']} teamMain /> <RoomTypeIcon size={30} type='p' style={{ margin: 10 }} /> </> ); diff --git a/app/containers/RoomTypeIcon/__snapshots__/RoomTypeIcon.test.tsx.snap b/app/containers/RoomTypeIcon/__snapshots__/RoomTypeIcon.test.tsx.snap index 4cf1e7eb8c0..d3f054edc7a 100644 --- a/app/containers/RoomTypeIcon/__snapshots__/RoomTypeIcon.test.tsx.snap +++ b/app/containers/RoomTypeIcon/__snapshots__/RoomTypeIcon.test.tsx.snap @@ -295,6 +295,68 @@ exports[`Story Snapshots: All should match snapshot 1`] = ` >  </Text>, + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#1F2329", + "fontSize": 30, + }, + [ + { + "lineHeight": 30, + }, + [ + { + "marginRight": 4, + }, + undefined, + ], + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text>, + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#1F2329", + "fontSize": 30, + }, + [ + { + "lineHeight": 30, + }, + [ + { + "marginRight": 4, + }, + undefined, + ], + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text>, <Text allowFontScaling={false} selectable={false} diff --git a/app/containers/RoomTypeIcon/index.tsx b/app/containers/RoomTypeIcon/index.tsx index 783c727c667..1dec36f0eed 100644 --- a/app/containers/RoomTypeIcon/index.tsx +++ b/app/containers/RoomTypeIcon/index.tsx @@ -7,7 +7,7 @@ import { CustomIcon, type TIconsName } from '../CustomIcon'; import { themes } from '../../lib/constants/colors'; import Status from '../Status'; import { useTheme } from '../../theme'; -import { type TUserStatus, type IOmnichannelSource } from '../../definitions'; +import { type TUserStatus, type IOmnichannelSource, type ISubscription } from '../../definitions'; const styles = StyleSheet.create({ icon: { @@ -24,10 +24,11 @@ interface IRoomTypeIcon { size?: number; style?: ViewStyle; sourceType?: IOmnichannelSource; + abacAttributes?: ISubscription['abacAttributes']; } const RoomTypeIcon = React.memo( - ({ userId, type, isGroupChat, status, style, teamMain, size = 16, sourceType }: IRoomTypeIcon) => { + ({ userId, type, isGroupChat, status, style, teamMain, size = 16, sourceType, abacAttributes }: IRoomTypeIcon) => { const { theme } = useTheme(); if (!type) { @@ -49,7 +50,9 @@ const RoomTypeIcon = React.memo( // TODO: move this to a separate function let icon: TIconsName = 'channel-private'; - if (teamMain) { + if (abacAttributes?.length) { + icon = teamMain ? 'team-shield' : 'hash-shield'; + } else if (teamMain) { icon = `teams${type === 'p' ? '-private' : ''}`; } else if (type === 'discussion') { icon = 'discussions'; diff --git a/app/definitions/ISubscription.ts b/app/definitions/ISubscription.ts index 17e09f329a1..ada68d0681b 100644 --- a/app/definitions/ISubscription.ts +++ b/app/definitions/ISubscription.ts @@ -116,6 +116,7 @@ export interface ISubscription { uploads: RelationModified<TUploadModel>; disableNotifications?: boolean; federated?: boolean; + abacAttributes?: string[]; } export type TSubscriptionModel = ISubscription & diff --git a/app/lib/database/model/Subscription.js b/app/lib/database/model/Subscription.js index 396817283bb..50eb2260cf2 100644 --- a/app/lib/database/model/Subscription.js +++ b/app/lib/database/model/Subscription.js @@ -153,6 +153,8 @@ export default class Subscription extends Model { @field('federated') federated; + @json('abac_attributes', sanitizer) abacAttributes; + asPlain() { return { _id: this._id, @@ -219,7 +221,8 @@ export default class Subscription extends Model { usersCount: this.usersCount, source: this.source, disableNotifications: this.disableNotifications, - federated: this.federated + federated: this.federated, + abacAttributes: this.abacAttributes }; } } diff --git a/app/lib/database/model/migrations.js b/app/lib/database/model/migrations.js index 601ece52607..6b0cef3b7c3 100644 --- a/app/lib/database/model/migrations.js +++ b/app/lib/database/model/migrations.js @@ -331,6 +331,15 @@ export default schemaMigrations({ columns: [{ name: 'federated', type: 'boolean', isOptional: true }] }) ] + }, + { + toVersion: 28, + steps: [ + addColumns({ + table: 'subscriptions', + columns: [{ name: 'abac_attributes', type: 'string', isOptional: true }] + }) + ] } ] }); diff --git a/app/lib/database/schema/app.js b/app/lib/database/schema/app.js index acca231cc08..f60705b7a17 100644 --- a/app/lib/database/schema/app.js +++ b/app/lib/database/schema/app.js @@ -1,7 +1,7 @@ import { appSchema, tableSchema } from '@nozbe/watermelondb'; export default appSchema({ - version: 27, + version: 28, tables: [ tableSchema({ name: 'subscriptions', @@ -70,7 +70,8 @@ export default appSchema({ { name: 'users_count', type: 'number', isOptional: true }, { name: 'unmuted', type: 'string', isOptional: true }, { name: 'disable_notifications', type: 'boolean', isOptional: true }, - { name: 'federated', type: 'boolean', isOptional: true } + { name: 'federated', type: 'boolean', isOptional: true }, + { name: 'abac_attributes', type: 'string', isOptional: true } ] }), tableSchema({ diff --git a/app/lib/methods/helpers/mergeSubscriptionsRooms.ts b/app/lib/methods/helpers/mergeSubscriptionsRooms.ts index a120a8e920c..2199c023272 100644 --- a/app/lib/methods/helpers/mergeSubscriptionsRooms.ts +++ b/app/lib/methods/helpers/mergeSubscriptionsRooms.ts @@ -34,6 +34,7 @@ export const merge = ( mergedSubscription.jitsiTimeout = room.jitsiTimeout; mergedSubscription.usernames = room.usernames; mergedSubscription.uids = room.uids; + mergedSubscription.abacAttributes = ['Classified', 'Top Secret', 'Confidential']; // TODO: remove this once we have the actual abac attributes } if (compareServerVersion(serverVersion, 'lowerThan', '3.7.0')) { diff --git a/app/views/RoomActionsView/index.tsx b/app/views/RoomActionsView/index.tsx index 400389faea6..e1fd6db97a5 100644 --- a/app/views/RoomActionsView/index.tsx +++ b/app/views/RoomActionsView/index.tsx @@ -795,6 +795,7 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction teamMain={room.teamMain} status={room.visitor?.status} sourceType={source} + abacAttributes={room.abacAttributes} /> <Text style={[styles.roomTitle, { color: themes[theme].fontTitlesLabels }]} numberOfLines={1}> {getRoomTitle(room)} diff --git a/app/views/RoomInfoView/components/RoomInfoViewTitle.tsx b/app/views/RoomInfoView/components/RoomInfoViewTitle.tsx index ebbd409af79..036413c5860 100644 --- a/app/views/RoomInfoView/components/RoomInfoViewTitle.tsx +++ b/app/views/RoomInfoView/components/RoomInfoViewTitle.tsx @@ -63,6 +63,7 @@ const RoomInfoViewTitle = ({ room, name, username, statusText, type }: IRoomInfo key='room-info-type' status={room?.visitor?.status} sourceType={room?.source} + abacAttributes={room?.abacAttributes} /> <Text testID='room-info-view-name' style={[styles.roomTitle, { color: colors.fontTitlesLabels }]} key='room-info-name'> {getRoomTitle(room)} diff --git a/app/views/RoomView/index.tsx b/app/views/RoomView/index.tsx index 4b76f4b55d0..5fa7ffedb9e 100644 --- a/app/views/RoomView/index.tsx +++ b/app/views/RoomView/index.tsx @@ -510,6 +510,7 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> { onPress={this.goRoomActionsView} testID={`room-view-title-${title}`} sourceType={sourceType} + abacAttributes={iSubRoom.abacAttributes} /> ), headerRight: () => ( diff --git a/ios/custom.ttf b/ios/custom.ttf index 410ec49c02906ac08dad8828039e339c8a15c963..b0758f2fa60ec7d33ab136418ed1aa939022731b 100644 GIT binary patch delta 1263 zcmZuxO>7%g5T1E&f8N^JeO~W+O^DmtyYWv5CH`B-G(R9N90Do|6{n!ol#&S5X-X3* zaHw<TKm-j}q#U>)fdm8uhe}wSxu6!QNR_Gr34(Ghssu`yUDFCE*1VlJ^Jc#JX5{zY z{+7S{J?{YmKoT~AL-pkI6Lp!^J@Q<kb^1)VvzmS3Y8L==WS?5<TwEocB0JJz>D=qD zs9(MIJJ}lmKW;9c?Yw-v_tJX+Ki#GC)-pNtua$2A_Nru$E_c^9KG>lh?41JOAD%mZ z=JC#*n~!b*{6bE=-tBCx!d)x^{Cb@n`IS!h>~{z4kH{uKd}H<e#Wf;Izu(s0`SNMp zzl?LZzxxb+ezPY44*PtQ_u*OChCbXNAO%zCQ)0_IhF<FloW*S2YaGQaNe+*otLYa0 zQ-XqD3LeAqzhwri&9K>;oW)48C13ZoNZMGlA{4JtsP|ek*esQ+evNXgrCN*=l%hC^ zaglM1Q3-y6c0qX-?~@`r6rz<Tkgx}kQ<%eACh$uH+nOvMjoFUl3{GR%s1J$__!M0) z`v~>|U&|1adTTO9qfDaQQ0rdC)doiPUPRa|73&@iA!?mSm7>;g-5qlrr{bvYc!sIW z&LvHoF{UI1QyAk+5vp(!2Y)b?Ye`iV3i;?nB<VCId&WZ+IYQmmDG3>qwqqigjxCWa zWE{E1g%rq96;e;Qh9GMI?NG{}R^AetrJ*cHRj3(%NcvK6m2=e|3W9QLIK%pe(XQn4 zrh}Mp6O?;!85tsu6pOu)q$`X}A~oiPb93P#RNC!Iv`oh_Y2j6WahR*ZSP6m^L#TXs z5wB^e={gD~n8q~Ml;sT7Ti1!56Eh=PDk=&hC(>lZ{W=K>xP<79rINNr)u*X9>>-Mr zeJQH8o<3%fo0vrzq&ZC}9zx`$j2Cs(2$9iVV+uENX_Xulp)0i^8*#Q(u4T){XyRdO zsnQO0ige7SXx6qt-=D35T^t!H>Y6p2Fy&kr&gI)r#m!dQPsZI+$9-v8^HV1l(&>d0 zQ}dQ3f!)6$GjNh_Mcq4s(PaqiLP#pJEt|)C|MSN<Z8}?8I`J`rU9fhd4tJs=hY)=S z_TOH7>wzJ2BD9mvTZiz8>FRGjkU|i64=69K#(y}+&l5dSTd#hxyC|pcKvIdWKRqat po}q!>9=$b*w|5tAz0bFw`$2rVcMXRw%wOooxwkRcy|Mop{ssNM!|DJ4 delta 272 zcmbPolX=2L=6VK31_lOhh6V;^1_S?KeItG$b`hY+9w1Ig&P^;354)Vrz`!U2<cFju z78d|%0U#elbEM}~rWwoE><98I7#Qw%WTYmhXh-+~`45583}zWX0ro>Ir+|D5AYUaT zx1?g>0+7_h7zPIBB{})YmWeGryUsB%JOv6eUdc_YC}8-;sK~(Z><UmoAulmE_3A&1 zwLtzCpnO$9esKxVp+NAWVB!vU#wU{)y&0cu_F>$5Um4^NAl6!VJ~N)*<|_j?3rHQq n6PZ?^aS(d4%u{p5mzzVLE@9sE@(Lpd*zYeH<u^ZgwS^G?iCayQ From ab9100a81c73e9c25fdb4910699fce4f64d24c40 Mon Sep 17 00:00:00 2001 From: Diego Mello <diegolmello@gmail.com> Date: Wed, 3 Dec 2025 14:38:12 -0300 Subject: [PATCH 2/6] feat(ABAC): Show system message when a member is removed (#6760) --- app/containers/message/Message.stories.tsx | 4 + .../__snapshots__/Message.test.tsx.snap | 910 +++++++++++++++--- app/containers/message/utils.ts | 5 +- app/definitions/IMessage.ts | 3 +- app/i18n/locales/ar.json | 1 + app/i18n/locales/bn-IN.json | 1 + app/i18n/locales/cs.json | 1 + app/i18n/locales/de.json | 1 + app/i18n/locales/en.json | 1 + app/i18n/locales/es.json | 1 + app/i18n/locales/fi.json | 1 + app/i18n/locales/fr.json | 1 + app/i18n/locales/hi-IN.json | 1 + app/i18n/locales/hu.json | 1 + app/i18n/locales/it.json | 1 + app/i18n/locales/ja.json | 1 + app/i18n/locales/nl.json | 1 + app/i18n/locales/nn.json | 1 + app/i18n/locales/no.json | 1 + app/i18n/locales/pt-BR.json | 1 + app/i18n/locales/pt-PT.json | 1 + app/i18n/locales/ru.json | 1 + app/i18n/locales/sl-SI.json | 1 + app/i18n/locales/sv.json | 1 + app/i18n/locales/ta-IN.json | 1 + app/i18n/locales/te-IN.json | 1 + app/i18n/locales/tr.json | 1 + app/i18n/locales/zh-CN.json | 1 + app/i18n/locales/zh-TW.json | 1 + 29 files changed, 832 insertions(+), 115 deletions(-) diff --git a/app/containers/message/Message.stories.tsx b/app/containers/message/Message.stories.tsx index 7f512e9b0cd..c56ee54143c 100644 --- a/app/containers/message/Message.stories.tsx +++ b/app/containers/message/Message.stories.tsx @@ -1962,6 +1962,8 @@ export const SystemMessages = () => ( <Message type='user-converted-to-channel' isInfo msg='channel-name' /> <Message type='user-deleted-room-from-team' isInfo msg='channel-name' /> <Message type='user-removed-room-from-team' isInfo msg='channel-name' /> + <Message type='abac-removed-user-from-room' isInfo /> + <Message type='unsupported' isInfo /> </> ); @@ -2003,6 +2005,8 @@ export const SystemMessagesLargeFont = () => ( <MessageLargeFont type='user-converted-to-channel' isInfo msg='channel-name' /> <MessageLargeFont type='user-deleted-room-from-team' isInfo msg='channel-name' /> <MessageLargeFont type='user-removed-room-from-team' isInfo msg='channel-name' /> + <MessageLargeFont type='abac-removed-user-from-room' isInfo /> + <MessageLargeFont type='unsupported' isInfo /> </> ); diff --git a/app/containers/message/__snapshots__/Message.test.tsx.snap b/app/containers/message/__snapshots__/Message.test.tsx.snap index b6ae6062194..7b9e409c565 100644 --- a/app/containers/message/__snapshots__/Message.test.tsx.snap +++ b/app/containers/message/__snapshots__/Message.test.tsx.snap @@ -93624,6 +93624,348 @@ exports[`Story Snapshots: SystemMessages should match snapshot 1`] = ` </View> </View> </View> + <View> + <View + style={ + [ + { + "flexDirection": "column", + "gap": 8, + "paddingHorizontal": 12, + "paddingVertical": 4, + "width": "100%", + }, + { + "marginTop": 4, + }, + ] + } + > + <View + accessibilityLabel="diego.mello 10:00:00 AM was removed by ABAC. " + accessible={true} + style={ + [ + { + "flexDirection": "row", + }, + { + "alignItems": "center", + }, + ] + } + > + <View + style={ + { + "alignItems": "flex-end", + "width": 36, + } + } + > + <View + accessible={true} + style={ + [ + { + "borderRadius": 4, + "height": 20, + "width": 20, + }, + undefined, + ] + } + testID="avatar" + > + <View + accessibilityLabel="diego.mello's avatar" + accessibilityState={ + { + "busy": undefined, + "checked": undefined, + "disabled": undefined, + "expanded": undefined, + "selected": undefined, + } + } + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + collapsable={false} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + { + "opacity": 1, + } + } + > + <ViewManagerAdapter_ExpoImage + borderRadius={4} + containerViewRef={"[React.ref]"} + contentFit="cover" + contentPosition={ + { + "left": "50%", + "top": "50%", + } + } + height={20} + nativeViewRef={"[React.ref]"} + onError={[Function]} + onLoad={[Function]} + onLoadStart={[Function]} + onProgress={[Function]} + placeholder={[]} + priority="high" + source={ + [ + { + "headers": { + "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)", + }, + "uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=40", + }, + ] + } + style={ + { + "borderRadius": 4, + "height": 20, + "width": 20, + } + } + transition={null} + width={20} + /> + </View> + </View> + </View> + <View + style={ + { + "flex": 1, + "marginLeft": 10, + } + } + > + <Text> + <Text + onPress={[Function]} + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + diego.mello + </Text> + + <Text + accessibilityLabel="was removed by ABAC" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "textAlign": "left", + }, + { + "color": "#6C727A", + }, + ] + } + > + was removed by ABAC + </Text> + </Text> + </View> + </View> + </View> + </View> + <View> + <View + style={ + [ + { + "flexDirection": "column", + "gap": 8, + "paddingHorizontal": 12, + "paddingVertical": 4, + "width": "100%", + }, + { + "marginTop": 4, + }, + ] + } + > + <View + accessibilityLabel="diego.mello 10:00:00 AM Unsupported system message. " + accessible={true} + style={ + [ + { + "flexDirection": "row", + }, + { + "alignItems": "center", + }, + ] + } + > + <View + style={ + { + "alignItems": "flex-end", + "width": 36, + } + } + > + <View + accessible={true} + style={ + [ + { + "borderRadius": 4, + "height": 20, + "width": 20, + }, + undefined, + ] + } + testID="avatar" + > + <View + accessibilityLabel="diego.mello's avatar" + accessibilityState={ + { + "busy": undefined, + "checked": undefined, + "disabled": undefined, + "expanded": undefined, + "selected": undefined, + } + } + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + collapsable={false} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + { + "opacity": 1, + } + } + > + <ViewManagerAdapter_ExpoImage + borderRadius={4} + containerViewRef={"[React.ref]"} + contentFit="cover" + contentPosition={ + { + "left": "50%", + "top": "50%", + } + } + height={20} + nativeViewRef={"[React.ref]"} + onError={[Function]} + onLoad={[Function]} + onLoadStart={[Function]} + onProgress={[Function]} + placeholder={[]} + priority="high" + source={ + [ + { + "headers": { + "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)", + }, + "uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=40", + }, + ] + } + style={ + { + "borderRadius": 4, + "height": 20, + "width": 20, + } + } + transition={null} + width={20} + /> + </View> + </View> + </View> + <View + style={ + { + "flex": 1, + "marginLeft": 10, + } + } + > + <Text + accessibilityLabel="Unsupported system message" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "textAlign": "left", + }, + { + "color": "#6C727A", + }, + ] + } + > + Unsupported system message + </Text> + </View> + </View> + </View> + </View> </View> </RCTScrollView> `; @@ -93655,7 +93997,371 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM message removed. " + accessibilityLabel="diego.mello 10:00:00 AM message removed. " + accessible={true} + style={ + [ + { + "flexDirection": "row", + }, + { + "alignItems": "center", + }, + ] + } + > + <View + style={ + { + "alignItems": "flex-end", + "width": 46.800000000000004, + } + } + > + <View + accessible={true} + style={ + [ + { + "borderRadius": 4, + "height": 26, + "width": 26, + }, + undefined, + ] + } + testID="avatar" + > + <View + accessibilityLabel="diego.mello's avatar" + accessibilityState={ + { + "busy": undefined, + "checked": undefined, + "disabled": undefined, + "expanded": undefined, + "selected": undefined, + } + } + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + collapsable={false} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + { + "opacity": 1, + } + } + > + <ViewManagerAdapter_ExpoImage + borderRadius={4} + containerViewRef={"[React.ref]"} + contentFit="cover" + contentPosition={ + { + "left": "50%", + "top": "50%", + } + } + height={26} + nativeViewRef={"[React.ref]"} + onError={[Function]} + onLoad={[Function]} + onLoadStart={[Function]} + onProgress={[Function]} + placeholder={[]} + priority="high" + source={ + [ + { + "headers": { + "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)", + }, + "uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=52", + }, + ] + } + style={ + { + "borderRadius": 4, + "height": 26, + "width": 26, + } + } + transition={null} + width={26} + /> + </View> + </View> + </View> + <View + style={ + { + "flex": 1, + "marginLeft": 10, + } + } + > + <Text> + <Text + onPress={[Function]} + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + diego.mello + </Text> + + <Text + accessibilityLabel="message removed" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "textAlign": "left", + }, + { + "color": "#6C727A", + }, + ] + } + > + message removed + </Text> + </Text> + </View> + </View> + </View> + </View> + <View> + <View + style={ + [ + { + "flexDirection": "column", + "gap": 8, + "paddingHorizontal": 12, + "paddingVertical": 4, + "width": "100%", + }, + { + "marginTop": 4, + }, + ] + } + > + <View + accessibilityLabel="diego.mello 10:00:00 AM joined the channel. " + accessible={true} + style={ + [ + { + "flexDirection": "row", + }, + { + "alignItems": "center", + }, + ] + } + > + <View + style={ + { + "alignItems": "flex-end", + "width": 46.800000000000004, + } + } + > + <View + accessible={true} + style={ + [ + { + "borderRadius": 4, + "height": 26, + "width": 26, + }, + undefined, + ] + } + testID="avatar" + > + <View + accessibilityLabel="diego.mello's avatar" + accessibilityState={ + { + "busy": undefined, + "checked": undefined, + "disabled": undefined, + "expanded": undefined, + "selected": undefined, + } + } + accessibilityValue={ + { + "max": undefined, + "min": undefined, + "now": undefined, + "text": undefined, + } + } + accessible={true} + collapsable={false} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + { + "opacity": 1, + } + } + > + <ViewManagerAdapter_ExpoImage + borderRadius={4} + containerViewRef={"[React.ref]"} + contentFit="cover" + contentPosition={ + { + "left": "50%", + "top": "50%", + } + } + height={26} + nativeViewRef={"[React.ref]"} + onError={[Function]} + onLoad={[Function]} + onLoadStart={[Function]} + onProgress={[Function]} + placeholder={[]} + priority="high" + source={ + [ + { + "headers": { + "User-Agent": "RC Mobile; ios unknown; vunknown (unknown)", + }, + "uri": "https://open.rocket.chat/avatar/diego.mello?format=png&size=52", + }, + ] + } + style={ + { + "borderRadius": 4, + "height": 26, + "width": 26, + } + } + transition={null} + width={26} + /> + </View> + </View> + </View> + <View + style={ + { + "flex": 1, + "marginLeft": 10, + } + } + > + <Text> + <Text + onPress={[Function]} + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + diego.mello + </Text> + + <Text + accessibilityLabel="joined the channel" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "textAlign": "left", + }, + { + "color": "#6C727A", + }, + ] + } + > + joined the channel + </Text> + </Text> + </View> + </View> + </View> + </View> + <View> + <View + style={ + [ + { + "flexDirection": "column", + "gap": 8, + "paddingHorizontal": 12, + "paddingVertical": 4, + "width": "100%", + }, + { + "marginTop": 4, + }, + ] + } + > + <View + accessibilityLabel="diego.mello 10:00:00 AM Pinned a message:. " accessible={true} style={ [ @@ -93796,7 +94502,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="message removed" + accessibilityLabel="Pinned a message:" style={ [ { @@ -93812,9 +94518,12 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - message removed + Pinned a message: </Text> </Text> + <View + pointerEvents="none" + /> </View> </View> </View> @@ -93837,7 +94546,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM joined the channel. " + accessibilityLabel="diego.mello 10:00:00 AM left the channel. " accessible={true} style={ [ @@ -93978,7 +94687,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="joined the channel" + accessibilityLabel="left the channel" style={ [ { @@ -93994,7 +94703,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - joined the channel + left the channel </Text> </Text> </View> @@ -94019,7 +94728,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM Pinned a message:. " + accessibilityLabel="diego.mello 10:00:00 AM removed rocket.cat. " accessible={true} style={ [ @@ -94160,7 +94869,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="Pinned a message:" + accessibilityLabel="removed rocket.cat" style={ [ { @@ -94176,12 +94885,9 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - Pinned a message: + removed rocket.cat </Text> </Text> - <View - pointerEvents="none" - /> </View> </View> </View> @@ -94204,7 +94910,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM left the channel. " + accessibilityLabel="diego.mello 10:00:00 AM added rocket.cat. " accessible={true} style={ [ @@ -94345,7 +95051,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="left the channel" + accessibilityLabel="added rocket.cat" style={ [ { @@ -94361,7 +95067,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - left the channel + added rocket.cat </Text> </Text> </View> @@ -94386,7 +95092,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM removed rocket.cat. " + accessibilityLabel="diego.mello 10:00:00 AM muted rocket.cat. " accessible={true} style={ [ @@ -94527,7 +95233,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="removed rocket.cat" + accessibilityLabel="muted rocket.cat" style={ [ { @@ -94543,7 +95249,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - removed rocket.cat + muted rocket.cat </Text> </Text> </View> @@ -94568,7 +95274,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM added rocket.cat. " + accessibilityLabel="diego.mello 10:00:00 AM unmuted rocket.cat. " accessible={true} style={ [ @@ -94709,7 +95415,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="added rocket.cat" + accessibilityLabel="unmuted rocket.cat" style={ [ { @@ -94725,7 +95431,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - added rocket.cat + unmuted rocket.cat </Text> </Text> </View> @@ -94750,7 +95456,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM muted rocket.cat. " + accessibilityLabel="diego.mello 10:00:00 AM defined rocket.cat as admin. " accessible={true} style={ [ @@ -94891,7 +95597,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="muted rocket.cat" + accessibilityLabel="defined rocket.cat as admin" style={ [ { @@ -94907,7 +95613,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - muted rocket.cat + defined rocket.cat as admin </Text> </Text> </View> @@ -94932,7 +95638,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM unmuted rocket.cat. " + accessibilityLabel="diego.mello 10:00:00 AM removed rocket.cat as admin. " accessible={true} style={ [ @@ -95073,7 +95779,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="unmuted rocket.cat" + accessibilityLabel="removed rocket.cat as admin" style={ [ { @@ -95089,7 +95795,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - unmuted rocket.cat + removed rocket.cat as admin </Text> </Text> </View> @@ -95114,7 +95820,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM defined rocket.cat as admin. " + accessibilityLabel="diego.mello 10:00:00 AM changed room name to: New name. " accessible={true} style={ [ @@ -95255,7 +95961,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="defined rocket.cat as admin" + accessibilityLabel="changed room name to: New name" style={ [ { @@ -95271,7 +95977,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - defined rocket.cat as admin + changed room name to: New name </Text> </Text> </View> @@ -95296,7 +96002,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM removed rocket.cat as admin. " + accessibilityLabel="diego.mello 10:00:00 AM changed room description to: new description. " accessible={true} style={ [ @@ -95437,7 +96143,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="removed rocket.cat as admin" + accessibilityLabel="changed room description to: new description" style={ [ { @@ -95453,7 +96159,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - removed rocket.cat as admin + changed room description to: new description </Text> </Text> </View> @@ -95478,7 +96184,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM changed room name to: New name. " + accessibilityLabel="diego.mello 10:00:00 AM changed room announcement to: new announcement. " accessible={true} style={ [ @@ -95619,7 +96325,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="changed room name to: New name" + accessibilityLabel="changed room announcement to: new announcement" style={ [ { @@ -95635,7 +96341,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - changed room name to: New name + changed room announcement to: new announcement </Text> </Text> </View> @@ -95660,7 +96366,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM changed room description to: new description. " + accessibilityLabel="diego.mello 10:00:00 AM changed room topic to: new topic. " accessible={true} style={ [ @@ -95801,7 +96507,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="changed room description to: new description" + accessibilityLabel="changed room topic to: new topic" style={ [ { @@ -95817,7 +96523,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - changed room description to: new description + changed room topic to: new topic </Text> </Text> </View> @@ -95842,7 +96548,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM changed room announcement to: new announcement. " + accessibilityLabel="diego.mello 10:00:00 AM changed room to public. " accessible={true} style={ [ @@ -95983,7 +96689,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="changed room announcement to: new announcement" + accessibilityLabel="changed room to public" style={ [ { @@ -95999,7 +96705,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - changed room announcement to: new announcement + changed room to public </Text> </Text> </View> @@ -96024,7 +96730,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM changed room topic to: new topic. " + accessibilityLabel="diego.mello 10:00:00 AM disabled E2E encryption for this room. " accessible={true} style={ [ @@ -96165,7 +96871,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="changed room topic to: new topic" + accessibilityLabel="disabled E2E encryption for this room" style={ [ { @@ -96181,7 +96887,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - changed room topic to: new topic + disabled E2E encryption for this room </Text> </Text> </View> @@ -96206,7 +96912,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM changed room to public. " + accessibilityLabel="diego.mello 10:00:00 AM enabled E2E encryption for this room. " accessible={true} style={ [ @@ -96347,7 +97053,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="changed room to public" + accessibilityLabel="enabled E2E encryption for this room" style={ [ { @@ -96363,7 +97069,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - changed room to public + enabled E2E encryption for this room </Text> </Text> </View> @@ -96388,7 +97094,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM disabled E2E encryption for this room. " + accessibilityLabel="diego.mello 10:00:00 AM removed @rocket.cat from this team. " accessible={true} style={ [ @@ -96529,7 +97235,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="disabled E2E encryption for this room" + accessibilityLabel="removed @rocket.cat from this team" style={ [ { @@ -96545,7 +97251,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - disabled E2E encryption for this room + removed @rocket.cat from this team </Text> </Text> </View> @@ -96570,7 +97276,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM enabled E2E encryption for this room. " + accessibilityLabel="diego.mello 10:00:00 AM added @rocket.cat to this team. " accessible={true} style={ [ @@ -96711,7 +97417,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="enabled E2E encryption for this room" + accessibilityLabel="added @rocket.cat to this team" style={ [ { @@ -96727,7 +97433,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - enabled E2E encryption for this room + added @rocket.cat to this team </Text> </Text> </View> @@ -96752,7 +97458,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM removed @rocket.cat from this team. " + accessibilityLabel="diego.mello 10:00:00 AM added #channel-name to this team. " accessible={true} style={ [ @@ -96893,7 +97599,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="removed @rocket.cat from this team" + accessibilityLabel="added #channel-name to this team" style={ [ { @@ -96909,7 +97615,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - removed @rocket.cat from this team + added #channel-name to this team </Text> </Text> </View> @@ -96934,7 +97640,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM added @rocket.cat to this team. " + accessibilityLabel="diego.mello 10:00:00 AM converted #channel-name to a team. " accessible={true} style={ [ @@ -97075,7 +97781,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="added @rocket.cat to this team" + accessibilityLabel="converted #channel-name to a team" style={ [ { @@ -97091,7 +97797,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - added @rocket.cat to this team + converted #channel-name to a team </Text> </Text> </View> @@ -97116,7 +97822,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM added #channel-name to this team. " + accessibilityLabel="diego.mello 10:00:00 AM converted #channel-name to channel. " accessible={true} style={ [ @@ -97257,7 +97963,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="added #channel-name to this team" + accessibilityLabel="converted #channel-name to channel" style={ [ { @@ -97273,7 +97979,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - added #channel-name to this team + converted #channel-name to channel </Text> </Text> </View> @@ -97298,7 +98004,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM converted #channel-name to a team. " + accessibilityLabel="diego.mello 10:00:00 AM deleted #channel-name. " accessible={true} style={ [ @@ -97439,7 +98145,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="converted #channel-name to a team" + accessibilityLabel="deleted #channel-name" style={ [ { @@ -97455,7 +98161,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - converted #channel-name to a team + deleted #channel-name </Text> </Text> </View> @@ -97480,7 +98186,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM converted #channel-name to channel. " + accessibilityLabel="diego.mello 10:00:00 AM removed #channel-name from this team. " accessible={true} style={ [ @@ -97621,7 +98327,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="converted #channel-name to channel" + accessibilityLabel="removed #channel-name from this team" style={ [ { @@ -97637,7 +98343,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - converted #channel-name to channel + removed #channel-name from this team </Text> </Text> </View> @@ -97662,7 +98368,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM deleted #channel-name. " + accessibilityLabel="diego.mello 10:00:00 AM was removed by ABAC. " accessible={true} style={ [ @@ -97803,7 +98509,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` </Text> <Text - accessibilityLabel="deleted #channel-name" + accessibilityLabel="was removed by ABAC" style={ [ { @@ -97819,7 +98525,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` ] } > - deleted #channel-name + was removed by ABAC </Text> </Text> </View> @@ -97844,7 +98550,7 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } > <View - accessibilityLabel="diego.mello 10:00:00 AM removed #channel-name from this team. " + accessibilityLabel="diego.mello 10:00:00 AM Unsupported system message. " accessible={true} style={ [ @@ -97963,46 +98669,24 @@ exports[`Story Snapshots: SystemMessagesLargeFont should match snapshot 1`] = ` } } > - <Text> - <Text - onPress={[Function]} - style={ - [ - { - "backgroundColor": "transparent", - "fontFamily": "Inter", - "fontSize": 16, - "fontWeight": "500", - "textAlign": "left", - }, - { - "color": "#1F2329", - }, - ] - } - > - diego.mello - </Text> - - <Text - accessibilityLabel="removed #channel-name from this team" - style={ - [ - { - "backgroundColor": "transparent", - "fontFamily": "Inter", - "fontSize": 16, - "fontWeight": "400", - "textAlign": "left", - }, - { - "color": "#6C727A", - }, - ] - } - > - removed #channel-name from this team - </Text> + <Text + accessibilityLabel="Unsupported system message" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "textAlign": "left", + }, + { + "color": "#6C727A", + }, + ] + } + > + Unsupported system message </Text> </View> </View> diff --git a/app/containers/message/utils.ts b/app/containers/message/utils.ts index 384d0fac67c..fef218699d0 100644 --- a/app/containers/message/utils.ts +++ b/app/containers/message/utils.ts @@ -75,7 +75,8 @@ const messagesWithAuthorName: MessageTypesValues[] = [ 'user-unmuted', 'room-unarchived', 'subscription-role-added', - 'subscription-role-removed' + 'subscription-role-removed', + 'abac-removed-user-from-room' ]; export const messageHaveAuthorName = (type: MessageTypesValues): boolean => messagesWithAuthorName.includes(type); @@ -159,6 +160,8 @@ export const getInfoMessage = ({ type, role, msg, author, comment }: TInfoMessag return I18n.t('Removed_user_as_role', { user: msg, role }); case 'message_pinned': return I18n.t('Pinned_a_message'); + case 'abac-removed-user-from-room': + return I18n.t('abac_removed_user_from_the_room'); // without author name case 'ul': diff --git a/app/definitions/IMessage.ts b/app/definitions/IMessage.ts index adeb8718f8d..6842f7399c8 100644 --- a/app/definitions/IMessage.ts +++ b/app/definitions/IMessage.ts @@ -250,7 +250,8 @@ export type MessageTypesValues = | OtrSystemMessages | 'message_pinned' | 'message_snippeted' - | 'jitsi_call_started'; + | 'jitsi_call_started' + | 'abac-removed-user-from-room'; export interface IAttachmentTranslations { [k: string]: string; diff --git a/app/i18n/locales/ar.json b/app/i18n/locales/ar.json index a0746a5f14e..873465a69da 100644 --- a/app/i18n/locales/ar.json +++ b/app/i18n/locales/ar.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "رسالة جديدة من {{name}}: {{message}}", "A11y_incoming_call_dismiss": "تجاهل", "A11y_incoming_call_swipe_down_to_view_options": "اسحب لأسفل لعرض الخيارات", + "abac_removed_user_from_the_room": "تمت إزالته بواسطة ABAC", "Accessibility": "إمكانية الوصول", "Accessibility_and_Appearance": "إمكانية الوصول والمظهر", "Accessibility_statement": "بيان الوصول", diff --git a/app/i18n/locales/bn-IN.json b/app/i18n/locales/bn-IN.json index 95b146f28ed..cc7589c2f7f 100644 --- a/app/i18n/locales/bn-IN.json +++ b/app/i18n/locales/bn-IN.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "{{name}} থেকে নতুন বার্তা: {{message}}", "A11y_incoming_call_dismiss": "বন্ধ করুন", "A11y_incoming_call_swipe_down_to_view_options": "নির্বাচনগুলি দেখতে নিচে সোয়াইপ করুন", + "abac_removed_user_from_the_room": "ABAC দ্বারা সরানো হয়েছে", "accept": "গ্রহণ করুন", "Accessibility": "অ্যাক্সেসিবিলিটি", "Accessibility_and_Appearance": "অ্যাক্সেসিবিলিটি ও চেহারা", diff --git a/app/i18n/locales/cs.json b/app/i18n/locales/cs.json index 9af2efdfae6..fb8e32d4f9d 100644 --- a/app/i18n/locales/cs.json +++ b/app/i18n/locales/cs.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Nová zpráva od {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Zavřít", "A11y_incoming_call_swipe_down_to_view_options": "Přejetím dolů zobrazíte možnosti", + "abac_removed_user_from_the_room": "byl odstraněn pomocí ABAC", "accept": "Akceptovat", "Accessibility": "Přístupnost", "Accessibility_and_Appearance": "Přístupnost a vzhled", diff --git a/app/i18n/locales/de.json b/app/i18n/locales/de.json index c485902adc4..4a245f48cf0 100644 --- a/app/i18n/locales/de.json +++ b/app/i18n/locales/de.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Neue Nachricht von {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Verwerfen", "A11y_incoming_call_swipe_down_to_view_options": "Nach unten wischen, um Optionen anzuzeigen", + "abac_removed_user_from_the_room": "wurde durch ABAC entfernt", "accept": "Annehmen", "Accessibility": "Barrierefreiheit", "Accessibility_and_Appearance": "Barrierefreiheit & Erscheinungsbild", diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 4c36b2afa3b..1435ae4c19d 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "New message from {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dismiss", "A11y_incoming_call_swipe_down_to_view_options": "Swipe down to view options", + "abac_removed_user_from_the_room": "was removed by ABAC", "accept": "Accept", "Accessibility": "Accessibility", "Accessibility_and_Appearance": "Accessibility & appearance", diff --git a/app/i18n/locales/es.json b/app/i18n/locales/es.json index 5ff50fe88f5..9561b081fbb 100644 --- a/app/i18n/locales/es.json +++ b/app/i18n/locales/es.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "Nuevo mensaje de {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Descartar", "A11y_incoming_call_swipe_down_to_view_options": "Desliza hacia abajo para ver opciones", + "abac_removed_user_from_the_room": "fue eliminado por ABAC", "Accessibility": "Accesibilidad", "Accessibility_and_Appearance": "Accesibilidad y apariencia", "Accessibility_statement": "Declaración de accesibilidad", diff --git a/app/i18n/locales/fi.json b/app/i18n/locales/fi.json index 02c4b692e3e..2327fe84c81 100644 --- a/app/i18n/locales/fi.json +++ b/app/i18n/locales/fi.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Uusi viesti {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Hylkää", "A11y_incoming_call_swipe_down_to_view_options": "Pyyhkäise alas nähdäksesi vaihtoehdot", + "abac_removed_user_from_the_room": "poistettiin ABAC:n toimesta", "Accessibility": "Saavutettavuus", "Accessibility_and_Appearance": "Saavutettavuus ja ulkonäkö", "Accessibility_statement": "Saavutettavuusilmoitus", diff --git a/app/i18n/locales/fr.json b/app/i18n/locales/fr.json index 477a3bdca92..de24f101df7 100644 --- a/app/i18n/locales/fr.json +++ b/app/i18n/locales/fr.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "Nouveau message de {{name}} : {{message}}", "A11y_incoming_call_dismiss": "Ignorer", "A11y_incoming_call_swipe_down_to_view_options": "Faites glisser vers le bas pour voir les options", + "abac_removed_user_from_the_room": "a été supprimé par ABAC", "Accessibility": "Accessibilité", "Accessibility_and_Appearance": "Accessibilité et apparence", "Accessibility_statement": "Déclaration d'accessibilité", diff --git a/app/i18n/locales/hi-IN.json b/app/i18n/locales/hi-IN.json index cc2f95777fe..0dbd91caa15 100644 --- a/app/i18n/locales/hi-IN.json +++ b/app/i18n/locales/hi-IN.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "{{name}} से नया संदेश: {{message}}", "A11y_incoming_call_dismiss": "खारिज करें", "A11y_incoming_call_swipe_down_to_view_options": "विकल्प देखने के लिए नीचे स्वाइप करें", + "abac_removed_user_from_the_room": "ABAC द्वारा हटाया गया", "accept": "स्वीकार करें", "Accessibility": "प्रवेशयोग्यता", "Accessibility_and_Appearance": "प्रवेशयोग्यता और दृश्यता", diff --git a/app/i18n/locales/hu.json b/app/i18n/locales/hu.json index 678ad46d8de..b6b1ec09c5c 100644 --- a/app/i18n/locales/hu.json +++ b/app/i18n/locales/hu.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Új üzenet érkezett {{name}}-tól: {{message}}", "A11y_incoming_call_dismiss": "Elutasítás", "A11y_incoming_call_swipe_down_to_view_options": "Húzza lefelé az opciók megtekintéséhez", + "abac_removed_user_from_the_room": "eltávolítva az ABAC által", "accept": "Elfogadom", "Accessibility": "Akadálymentesség", "Accessibility_and_Appearance": "Hozzáférhetőség és megjelenés", diff --git a/app/i18n/locales/it.json b/app/i18n/locales/it.json index cbbff6eb3b1..0f48f43cba6 100644 --- a/app/i18n/locales/it.json +++ b/app/i18n/locales/it.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Nuovo messaggio da {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Ignora", "A11y_incoming_call_swipe_down_to_view_options": "Scorri verso il basso per visualizzare le opzioni", + "abac_removed_user_from_the_room": "è stato rimosso da ABAC", "Accessibility": "Accessibilità", "Accessibility_and_Appearance": "Accessibilità e aspetto", "Accessibility_statement": "Dichiarazione di accessibilità", diff --git a/app/i18n/locales/ja.json b/app/i18n/locales/ja.json index 6eac408d43c..54006a2c665 100644 --- a/app/i18n/locales/ja.json +++ b/app/i18n/locales/ja.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "{{name}} からの新しいメッセージ: {{message}}", "A11y_incoming_call_dismiss": "閉じる", "A11y_incoming_call_swipe_down_to_view_options": "オプションを見るには下にスワイプしてください", + "abac_removed_user_from_the_room": "ABACによって削除されました", "Accessibility": "アクセシビリティ", "Accessibility_and_Appearance": "アクセシビリティと外観", "Accessibility_statement": "アクセシビリティ声明", diff --git a/app/i18n/locales/nl.json b/app/i18n/locales/nl.json index b4f0bbb4c89..784d7f4932a 100644 --- a/app/i18n/locales/nl.json +++ b/app/i18n/locales/nl.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "Nieuw bericht van {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Afwijzen", "A11y_incoming_call_swipe_down_to_view_options": "Veeg omlaag om opties te bekijken", + "abac_removed_user_from_the_room": "werd verwijderd door ABAC", "Accessibility": "Toegankelijkheid", "Accessibility_and_Appearance": "Toegankelijkheid & uiterlijk", "Accessibility_statement": "Toegankelijkheidsverklaring", diff --git a/app/i18n/locales/nn.json b/app/i18n/locales/nn.json index f89f7c77d64..f14bacb8020 100644 --- a/app/i18n/locales/nn.json +++ b/app/i18n/locales/nn.json @@ -7,6 +7,7 @@ "A11y_in_app_notification": "Ny melding frå {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Avslå", "A11y_incoming_call_swipe_down_to_view_options": "Sveip ned for å sjå alternativa", + "abac_removed_user_from_the_room": "vart fjerna av ABAC", "accept": "Aksepter", "Accessibility": "Tilgjengelighet", "Accessibility_and_Appearance": "Tilgjengelighet og utseende", diff --git a/app/i18n/locales/no.json b/app/i18n/locales/no.json index 6ba497f838c..854d2a1e202 100644 --- a/app/i18n/locales/no.json +++ b/app/i18n/locales/no.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Ny melding fra {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Avvis", "A11y_incoming_call_swipe_down_to_view_options": "Dra ned for å se alternativer", + "abac_removed_user_from_the_room": "ble fjernet av ABAC", "accept": "Aksepter", "Accessibility": "Tilgjengelighet", "Accessibility_and_Appearance": "Tilgjengelighet og utseende", diff --git a/app/i18n/locales/pt-BR.json b/app/i18n/locales/pt-BR.json index 541bfa95f2b..a633bd118b4 100644 --- a/app/i18n/locales/pt-BR.json +++ b/app/i18n/locales/pt-BR.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Nova mensagem de {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dispensar", "A11y_incoming_call_swipe_down_to_view_options": "Deslize para baixo para ver as opções", + "abac_removed_user_from_the_room": "foi removido pelo ABAC", "accept": "Aceitar", "Accessibility": "Acessibilidade", "Accessibility_and_Appearance": "Acessibilidade e aparência", diff --git a/app/i18n/locales/pt-PT.json b/app/i18n/locales/pt-PT.json index c6200efc916..9392036e3bf 100644 --- a/app/i18n/locales/pt-PT.json +++ b/app/i18n/locales/pt-PT.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "Nova mensagem de {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dispensar", "A11y_incoming_call_swipe_down_to_view_options": "Deslize para baixo para ver as opções.", + "abac_removed_user_from_the_room": "foi removido pelo ABAC", "Accessibility": "Acessibilidade", "Accessibility_and_Appearance": "Acessibilidade e aparência", "Accessibility_statement": "Declaração de acessibilidade", diff --git a/app/i18n/locales/ru.json b/app/i18n/locales/ru.json index 9f19d89f889..9be29162986 100644 --- a/app/i18n/locales/ru.json +++ b/app/i18n/locales/ru.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Новое сообщение от {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Отклонить", "A11y_incoming_call_swipe_down_to_view_options": "Проведите вниз, чтобы просмотреть варианты действий", + "abac_removed_user_from_the_room": "был удалён ABAC'ом", "Accessibility": "Доступность", "Accessibility_and_Appearance": "Доступность и внешний вид", "Accessibility_statement": "Заявление о доступности", diff --git a/app/i18n/locales/sl-SI.json b/app/i18n/locales/sl-SI.json index 31781d2b207..dcbf3aeaff3 100644 --- a/app/i18n/locales/sl-SI.json +++ b/app/i18n/locales/sl-SI.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Novo sporočilo od {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Opusti", "A11y_incoming_call_swipe_down_to_view_options": "Podrsnite navzdol za ogled možnosti", + "abac_removed_user_from_the_room": "je bil odstranjen s strani ABAC", "Accessibility": "Dostopnost", "Accessibility_and_Appearance": "Dostopnost in videz", "Accessibility_statement": "Izjava o dostopnosti", diff --git a/app/i18n/locales/sv.json b/app/i18n/locales/sv.json index 21c289591b7..a19bfde9387 100644 --- a/app/i18n/locales/sv.json +++ b/app/i18n/locales/sv.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "Nytt meddelande från {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Avvisa", "A11y_incoming_call_swipe_down_to_view_options": "Svep nedåt för att se alternativ", + "abac_removed_user_from_the_room": "togs bort av ABAC", "Accessibility": "Tillgänglighet", "Accessibility_and_Appearance": "Tillgänglighet och utseende", "Accessibility_statement": "Tillgänglighetsredogörelse", diff --git a/app/i18n/locales/ta-IN.json b/app/i18n/locales/ta-IN.json index b97024effdc..d33cc035f80 100644 --- a/app/i18n/locales/ta-IN.json +++ b/app/i18n/locales/ta-IN.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "{{name}}-இருந்து புதிய செய்தி: {{message}}", "A11y_incoming_call_dismiss": "தள்ளு", "A11y_incoming_call_swipe_down_to_view_options": "விருப்பங்களைப் பார்க்க கீழே நகர்த்தவும்", + "abac_removed_user_from_the_room": "ABAC மூலம் அகற்றப்பட்டது", "accept": "ஏற்றுக்கொள்", "Accessibility": "அணுகல் மேம்பாடு", "Accessibility_and_Appearance": "நுகர்வுத்திறன் மற்றும் தோற்றம்", diff --git a/app/i18n/locales/te-IN.json b/app/i18n/locales/te-IN.json index 682d2fa665c..39f56d3e6e4 100644 --- a/app/i18n/locales/te-IN.json +++ b/app/i18n/locales/te-IN.json @@ -12,6 +12,7 @@ "A11y_in_app_notification": "{{name}} నుండి కొత్త సందేశం: {{message}}", "A11y_incoming_call_dismiss": "ఖారు చేయండి", "A11y_incoming_call_swipe_down_to_view_options": "క్రిందికి స్వైప్ చేయి, పరామితులను చూడండి", + "abac_removed_user_from_the_room": "ABAC ద్వారా తొలగించబడింది", "accept": "అంగీకరించు", "Accessibility": "एक्सेसिबिलिटी", "Accessibility_and_Appearance": "प्रवेशयोग्यता और रूपरेखा", diff --git a/app/i18n/locales/tr.json b/app/i18n/locales/tr.json index 54bdecd83be..a49577e72ac 100644 --- a/app/i18n/locales/tr.json +++ b/app/i18n/locales/tr.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "Yeni mesaj {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dismiss et.", "A11y_incoming_call_swipe_down_to_view_options": "Aşağı kaydırarak seçenekleri görüntüle", + "abac_removed_user_from_the_room": "ABAC tarafından kaldırıldı", "Accessibility": "Erişilebilirlik", "Accessibility_and_Appearance": "Erişilebilirlik ve görünüm", "Accessibility_statement": "Erişilebilirlik beyanı", diff --git a/app/i18n/locales/zh-CN.json b/app/i18n/locales/zh-CN.json index 987c8fc7eff..b98af6e2e51 100644 --- a/app/i18n/locales/zh-CN.json +++ b/app/i18n/locales/zh-CN.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "来自{{name}}的新消息:{{message}}", "A11y_incoming_call_dismiss": "关闭", "A11y_incoming_call_swipe_down_to_view_options": "向下滑动以查看选项", + "abac_removed_user_from_the_room": "被ABAC删除", "Accessibility": "无障碍性", "Accessibility_and_Appearance": "辅助功能和外观", "Accessibility_statement": "无障碍声明", diff --git a/app/i18n/locales/zh-TW.json b/app/i18n/locales/zh-TW.json index bc818601579..e80257999eb 100644 --- a/app/i18n/locales/zh-TW.json +++ b/app/i18n/locales/zh-TW.json @@ -8,6 +8,7 @@ "A11y_in_app_notification": "來自 {{name}} 的新訊息:{{message}}", "A11y_incoming_call_dismiss": "關閉", "A11y_incoming_call_swipe_down_to_view_options": "向下滑動以查看選項", + "abac_removed_user_from_the_room": "被ABAC刪除", "Accessibility": "無障礙設施", "Accessibility_and_Appearance": "無障礙功能與外觀", "Accessibility_statement": "无障碍声明", From be49e7784ce5a94930cdfff4b42c3520d9d86514 Mon Sep 17 00:00:00 2001 From: Diego Mello <diegolmello@gmail.com> Date: Wed, 3 Dec 2025 14:40:11 -0300 Subject: [PATCH 3/6] feat(ABAC): Remove invite users on ABAC managed rooms (#6768) --- app/views/RoomMembersView/components/ActionsSection.tsx | 5 +++-- app/views/RoomMembersView/index.tsx | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/views/RoomMembersView/components/ActionsSection.tsx b/app/views/RoomMembersView/components/ActionsSection.tsx index 6cbe08571d4..5a831fb5623 100644 --- a/app/views/RoomMembersView/components/ActionsSection.tsx +++ b/app/views/RoomMembersView/components/ActionsSection.tsx @@ -23,9 +23,10 @@ interface IActionsSection { rid: TSubscriptionModel['rid']; t: TSubscriptionModel['t']; joined: boolean; + abacAttributes: TSubscriptionModel['abacAttributes']; } -export default function ActionsSection({ rid, t, joined }: IActionsSection): React.ReactElement { +export default function ActionsSection({ rid, t, joined, abacAttributes }: IActionsSection): React.ReactElement { const { navigate, pop } = useNavigation<TNavigation>(); const dispatch = useDispatch(); const [addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission, createInviteLinksPermission] = @@ -89,7 +90,7 @@ export default function ActionsSection({ rid, t, joined }: IActionsSection): Rea </> ) : null} - {['c', 'p'].includes(t) && canInviteUser ? ( + {['c', 'p'].includes(t) && canInviteUser && !abacAttributes ? ( <> <List.Item title='Invite_users' diff --git a/app/views/RoomMembersView/index.tsx b/app/views/RoomMembersView/index.tsx index 60dabe7de70..cacad557b09 100644 --- a/app/views/RoomMembersView/index.tsx +++ b/app/views/RoomMembersView/index.tsx @@ -406,7 +406,12 @@ const RoomMembersView = (): React.ReactElement => { ItemSeparatorComponent={List.Separator} ListHeaderComponent={ <> - <ActionsSection joined={params.joined as boolean} rid={state.room.rid} t={state.room.t} /> + <ActionsSection + joined={params.joined as boolean} + rid={state.room.rid} + t={state.room.t} + abacAttributes={state.room.abacAttributes} + /> <SearchBox onChangeText={text => updateState({ filter: text.trim() })} testID='room-members-view-search' /> </> } From ca4c9f953c2d7065d35f04f1935e77dc4ae2b5db Mon Sep 17 00:00:00 2001 From: Diego Mello <diegolmello@gmail.com> Date: Wed, 3 Dec 2025 14:46:17 -0300 Subject: [PATCH 4/6] feat(ABAC): Add room attributes to room info (#6761) --- app/containers/ActionSheet/Item.tsx | 2 +- app/containers/ActionSheet/Provider.tsx | 1 + app/containers/MessageActions/index.tsx | 14 +- .../RoomHeader/RoomHeader.stories.tsx | 17 +- app/containers/RoomItem/RoomItem.stories.tsx | 4 +- .../RoomTypeIcon/RoomTypeIcon.stories.tsx | 4 +- app/definitions/ISubscription.ts | 2 +- app/i18n/locales/ar.json | 4 + app/i18n/locales/bn-IN.json | 4 + app/i18n/locales/cs.json | 4 + app/i18n/locales/de.json | 4 + app/i18n/locales/en.json | 4 + app/i18n/locales/es.json | 4 + app/i18n/locales/fi.json | 4 + app/i18n/locales/fr.json | 4 + app/i18n/locales/hi-IN.json | 4 + app/i18n/locales/hu.json | 4 + app/i18n/locales/it.json | 4 + app/i18n/locales/ja.json | 4 + app/i18n/locales/nl.json | 4 + app/i18n/locales/nn.json | 4 + app/i18n/locales/no.json | 7 +- app/i18n/locales/pt-BR.json | 4 + app/i18n/locales/pt-PT.json | 4 + app/i18n/locales/ru.json | 4 + app/i18n/locales/sl-SI.json | 4 + app/i18n/locales/sv.json | 4 + app/i18n/locales/ta-IN.json | 4 + app/i18n/locales/te-IN.json | 4 + app/i18n/locales/tr.json | 4 + app/i18n/locales/zh-CN.json | 4 + app/i18n/locales/zh-TW.json | 4 + .../helpers/mergeSubscriptionsRooms.ts | 6 +- app/views/RoomInfoView/Channel.tsx | 2 + app/views/RoomInfoView/Direct.tsx | 14 +- app/views/RoomInfoView/Item.tsx | 10 +- .../RoomInfoView/components/ItemLabel.tsx | 18 + .../components/RoomInfoABAC.stories.tsx | 53 + .../components/RoomInfoABAC.test.tsx | 4 + .../RoomInfoView/components/RoomInfoABAC.tsx | 48 + .../RoomInfoView/components/RoomInfoTag.tsx | 22 + .../__snapshots__/RoomInfoABAC.test.tsx.snap | 2755 +++++++++++++++++ app/views/RoomInfoView/index.tsx | 2 +- app/views/RoomInfoView/styles.ts | 26 +- 44 files changed, 3066 insertions(+), 41 deletions(-) create mode 100644 app/views/RoomInfoView/components/ItemLabel.tsx create mode 100644 app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx create mode 100644 app/views/RoomInfoView/components/RoomInfoABAC.test.tsx create mode 100644 app/views/RoomInfoView/components/RoomInfoABAC.tsx create mode 100644 app/views/RoomInfoView/components/RoomInfoTag.tsx create mode 100644 app/views/RoomInfoView/components/__snapshots__/RoomInfoABAC.test.tsx.snap diff --git a/app/containers/ActionSheet/Item.tsx b/app/containers/ActionSheet/Item.tsx index 33e2d3bb476..0716b430eea 100644 --- a/app/containers/ActionSheet/Item.tsx +++ b/app/containers/ActionSheet/Item.tsx @@ -26,7 +26,7 @@ export const Item = React.memo(({ item, hide }: IActionSheetItem) => { hide(); item?.onPress(); } else { - EventEmitter.emit(LISTENER, { message: I18n.t('You_dont_have_permission_to_perform_this_action') }); + EventEmitter.emit(LISTENER, { message: item?.disabledReason || I18n.t('You_dont_have_permission_to_perform_this_action') }); } }; diff --git a/app/containers/ActionSheet/Provider.tsx b/app/containers/ActionSheet/Provider.tsx index 833dde87fd3..6de0804a344 100644 --- a/app/containers/ActionSheet/Provider.tsx +++ b/app/containers/ActionSheet/Provider.tsx @@ -14,6 +14,7 @@ export type TActionSheetOptionsItem = { onPress: () => void; right?: () => React.ReactElement; enabled?: boolean; + disabledReason?: string; }; export type TActionSheetOptions = { diff --git a/app/containers/MessageActions/index.tsx b/app/containers/MessageActions/index.tsx index 90a516ce0c0..8bee2970bd8 100644 --- a/app/containers/MessageActions/index.tsx +++ b/app/containers/MessageActions/index.tsx @@ -442,7 +442,8 @@ const MessageActions = React.memo( title: I18n.t('Reply_in_direct_message'), icon: 'arrow-back', onPress: () => handleReplyInDM(message), - enabled: permissions.hasCreateDirectMessagePermission + enabled: permissions.hasCreateDirectMessagePermission && !room.abacAttributes, + disabledReason: room.abacAttributes && I18n.t('ABAC_disabled_action_reason') }); } @@ -454,19 +455,24 @@ const MessageActions = React.memo( enabled: permissions.hasCreateDiscussionOtherUserPermission }); + // Forward if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.2.0') && !videoConfBlock) { options.push({ title: I18n.t('Forward'), icon: 'arrow-forward', - onPress: () => handleShareMessage(message) + onPress: () => handleShareMessage(message), + enabled: !room.abacAttributes, + disabledReason: room.abacAttributes && I18n.t('ABAC_disabled_action_reason') }); } - // Permalink + // Get link options.push({ title: I18n.t('Get_link'), icon: 'link', - onPress: () => handlePermalink(message) + onPress: () => handlePermalink(message), + enabled: !room.abacAttributes, + disabledReason: room.abacAttributes && I18n.t('ABAC_disabled_action_reason') }); // Copy diff --git a/app/containers/RoomHeader/RoomHeader.stories.tsx b/app/containers/RoomHeader/RoomHeader.stories.tsx index 3187cb4f0b6..2372e1bd305 100644 --- a/app/containers/RoomHeader/RoomHeader.stories.tsx +++ b/app/containers/RoomHeader/RoomHeader.stories.tsx @@ -55,8 +55,21 @@ export const Icons = () => ( <HeaderExample title={() => <RoomHeader title='busy dm' type='d' status='busy' />} /> <HeaderExample title={() => <RoomHeader title='loading dm' type='d' status='loading' />} /> <HeaderExample title={() => <RoomHeader title='offline dm' type='d' />} /> - <HeaderExample title={() => <RoomHeader title='classified' type='p' abacAttributes={['Classified']} />} /> - <HeaderExample title={() => <RoomHeader title='classified' type='p' abacAttributes={['Classified']} teamMain />} /> + <HeaderExample + title={() => ( + <RoomHeader title='classified' type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> + )} + /> + <HeaderExample + title={() => ( + <RoomHeader + title='classified' + type='p' + abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} + teamMain + /> + )} + /> </> ); diff --git a/app/containers/RoomItem/RoomItem.stories.tsx b/app/containers/RoomItem/RoomItem.stories.tsx index ccfcf93893b..074ede08b2c 100644 --- a/app/containers/RoomItem/RoomItem.stories.tsx +++ b/app/containers/RoomItem/RoomItem.stories.tsx @@ -71,8 +71,8 @@ export const Type = () => ( <RoomItem type='l' /> <RoomItem type='discussion' /> <RoomItem type='d' isGroupChat /> - <RoomItem type='p' abacAttributes={['Classified']} /> - <RoomItem type='p' abacAttributes={['Classified']} teamMain /> + <RoomItem type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> + <RoomItem type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} teamMain /> <RoomItem type='&' /> </> ); diff --git a/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx b/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx index 9181c98fc57..3e731182bab 100644 --- a/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx +++ b/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx @@ -18,8 +18,8 @@ export const All = () => ( <RoomTypeIcon size={30} type='p' teamMain /> <RoomTypeIcon size={30} type='discussion' /> <RoomTypeIcon size={30} type='l' status='away' sourceType={{ type: OmnichannelSourceType.SMS }} /> - <RoomTypeIcon size={30} type='p' abacAttributes={['Classified']} /> - <RoomTypeIcon size={30} type='p' abacAttributes={['Classified']} teamMain /> + <RoomTypeIcon size={30} type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> + <RoomTypeIcon size={30} type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} teamMain /> <RoomTypeIcon size={30} type='p' style={{ margin: 10 }} /> </> ); diff --git a/app/definitions/ISubscription.ts b/app/definitions/ISubscription.ts index ada68d0681b..0c7bc2b7262 100644 --- a/app/definitions/ISubscription.ts +++ b/app/definitions/ISubscription.ts @@ -116,7 +116,7 @@ export interface ISubscription { uploads: RelationModified<TUploadModel>; disableNotifications?: boolean; federated?: boolean; - abacAttributes?: string[]; + abacAttributes?: { name: string; values: string[] }[]; } export type TSubscriptionModel = ISubscription & diff --git a/app/i18n/locales/ar.json b/app/i18n/locales/ar.json index 873465a69da..597fac93b9e 100644 --- a/app/i18n/locales/ar.json +++ b/app/i18n/locales/ar.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "رسالة جديدة من {{name}}: {{message}}", "A11y_incoming_call_dismiss": "تجاهل", "A11y_incoming_call_swipe_down_to_view_options": "اسحب لأسفل لعرض الخيارات", + "ABAC_disabled_action_reason": "غير متاح في الغرف المدارة بواسطة ABAC", + "ABAC_managed": "مدار بواسطة ABAC", + "ABAC_managed_description": "فقط المستخدمون المتوافقون لديهم حق الوصول إلى الغرف التي يتم التحكم فيها بالوصول المستند إلى السمات. تحدد السمات الوصول إلى الغرفة.", "abac_removed_user_from_the_room": "تمت إزالته بواسطة ABAC", + "ABAC_room_attributes": "سمات الغرفة", "Accessibility": "إمكانية الوصول", "Accessibility_and_Appearance": "إمكانية الوصول والمظهر", "Accessibility_statement": "بيان الوصول", diff --git a/app/i18n/locales/bn-IN.json b/app/i18n/locales/bn-IN.json index cc7589c2f7f..a58e6274c96 100644 --- a/app/i18n/locales/bn-IN.json +++ b/app/i18n/locales/bn-IN.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "{{name}} থেকে নতুন বার্তা: {{message}}", "A11y_incoming_call_dismiss": "বন্ধ করুন", "A11y_incoming_call_swipe_down_to_view_options": "নির্বাচনগুলি দেখতে নিচে সোয়াইপ করুন", + "ABAC_disabled_action_reason": "ABAC-পরিচালিত রুমগুলিতে উপলব্ধ নয়", + "ABAC_managed": "ABAC দ্বারা পরিচালিত", + "ABAC_managed_description": "শুধুমাত্র অনুগত ব্যবহারকারীদের অ্যাট্রিবিউট-ভিত্তিক অ্যাক্সেস নিয়ন্ত্রিত রুমগুলিতে অ্যাক্সেস আছে। অ্যাট্রিবিউটগুলি রুমের অ্যাক্সেস নির্ধারণ করে।", "abac_removed_user_from_the_room": "ABAC দ্বারা সরানো হয়েছে", + "ABAC_room_attributes": "রুমের বৈশিষ্ট্য", "accept": "গ্রহণ করুন", "Accessibility": "অ্যাক্সেসিবিলিটি", "Accessibility_and_Appearance": "অ্যাক্সেসিবিলিটি ও চেহারা", diff --git a/app/i18n/locales/cs.json b/app/i18n/locales/cs.json index fb8e32d4f9d..7ac70a24c75 100644 --- a/app/i18n/locales/cs.json +++ b/app/i18n/locales/cs.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Nová zpráva od {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Zavřít", "A11y_incoming_call_swipe_down_to_view_options": "Přejetím dolů zobrazíte možnosti", + "ABAC_disabled_action_reason": "Není k dispozici v místnostech spravovaných systémem ABAC", + "ABAC_managed": "Spravováno ABAC", + "ABAC_managed_description": "Pouze vyhovující uživatelé mají přístup k místnostem řízeným přístupem na základě atributů. Atributy určují přístup k místnosti.", "abac_removed_user_from_the_room": "byl odstraněn pomocí ABAC", + "ABAC_room_attributes": "Atributy místnosti", "accept": "Akceptovat", "Accessibility": "Přístupnost", "Accessibility_and_Appearance": "Přístupnost a vzhled", diff --git a/app/i18n/locales/de.json b/app/i18n/locales/de.json index 4a245f48cf0..b8d56fe32c1 100644 --- a/app/i18n/locales/de.json +++ b/app/i18n/locales/de.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Neue Nachricht von {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Verwerfen", "A11y_incoming_call_swipe_down_to_view_options": "Nach unten wischen, um Optionen anzuzeigen", + "ABAC_disabled_action_reason": "Nicht verfügbar in ABAC-verwalteten Räumen", + "ABAC_managed": "ABAC verwaltet", + "ABAC_managed_description": "Nur konforme Benutzer haben Zugriff auf attributbasierte zugriffsgesteuerte Räume. Attribute bestimmen den Raumzugriff.", "abac_removed_user_from_the_room": "wurde durch ABAC entfernt", + "ABAC_room_attributes": "Raumattribute", "accept": "Annehmen", "Accessibility": "Barrierefreiheit", "Accessibility_and_Appearance": "Barrierefreiheit & Erscheinungsbild", diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 1435ae4c19d..214c054d46d 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "New message from {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dismiss", "A11y_incoming_call_swipe_down_to_view_options": "Swipe down to view options", + "ABAC_disabled_action_reason": "Not available in ABAC-managed rooms", + "ABAC_managed": "ABAC managed", + "ABAC_managed_description": "Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access.", "abac_removed_user_from_the_room": "was removed by ABAC", + "ABAC_room_attributes": "Room attributes", "accept": "Accept", "Accessibility": "Accessibility", "Accessibility_and_Appearance": "Accessibility & appearance", diff --git a/app/i18n/locales/es.json b/app/i18n/locales/es.json index 9561b081fbb..79762fda7b7 100644 --- a/app/i18n/locales/es.json +++ b/app/i18n/locales/es.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "Nuevo mensaje de {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Descartar", "A11y_incoming_call_swipe_down_to_view_options": "Desliza hacia abajo para ver opciones", + "ABAC_disabled_action_reason": "No disponible en salas gestionadas por ABAC", + "ABAC_managed": "Gestionado por ABAC", + "ABAC_managed_description": "Solo los usuarios compatibles tienen acceso a las salas controladas por acceso basado en atributos. Los atributos determinan el acceso a la sala.", "abac_removed_user_from_the_room": "fue eliminado por ABAC", + "ABAC_room_attributes": "Atributos de la sala", "Accessibility": "Accesibilidad", "Accessibility_and_Appearance": "Accesibilidad y apariencia", "Accessibility_statement": "Declaración de accesibilidad", diff --git a/app/i18n/locales/fi.json b/app/i18n/locales/fi.json index 2327fe84c81..97dd32c7340 100644 --- a/app/i18n/locales/fi.json +++ b/app/i18n/locales/fi.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Uusi viesti {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Hylkää", "A11y_incoming_call_swipe_down_to_view_options": "Pyyhkäise alas nähdäksesi vaihtoehdot", + "ABAC_disabled_action_reason": "Ei saatavilla ABAC-hallituissa huoneissa", + "ABAC_managed": "ABAC-hallittu", + "ABAC_managed_description": "Vain yhteensopivilla käyttäjillä on pääsy attribuuttipohjaisesti hallittuihin huoneisiin. Attribuutit määrittävät huoneen pääsyn.", "abac_removed_user_from_the_room": "poistettiin ABAC:n toimesta", + "ABAC_room_attributes": "Huoneen attribuutit", "Accessibility": "Saavutettavuus", "Accessibility_and_Appearance": "Saavutettavuus ja ulkonäkö", "Accessibility_statement": "Saavutettavuusilmoitus", diff --git a/app/i18n/locales/fr.json b/app/i18n/locales/fr.json index de24f101df7..8f1985d3230 100644 --- a/app/i18n/locales/fr.json +++ b/app/i18n/locales/fr.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "Nouveau message de {{name}} : {{message}}", "A11y_incoming_call_dismiss": "Ignorer", "A11y_incoming_call_swipe_down_to_view_options": "Faites glisser vers le bas pour voir les options", + "ABAC_disabled_action_reason": "Non disponible dans les salles gérées par ABAC", + "ABAC_managed": "Géré par ABAC", + "ABAC_managed_description": "Seuls les utilisateurs conformes ont accès aux salles contrôlées par accès basé sur les attributs. Les attributs déterminent l'accès à la salle.", "abac_removed_user_from_the_room": "a été supprimé par ABAC", + "ABAC_room_attributes": "Attributs de la salle", "Accessibility": "Accessibilité", "Accessibility_and_Appearance": "Accessibilité et apparence", "Accessibility_statement": "Déclaration d'accessibilité", diff --git a/app/i18n/locales/hi-IN.json b/app/i18n/locales/hi-IN.json index 0dbd91caa15..b1b5be41b74 100644 --- a/app/i18n/locales/hi-IN.json +++ b/app/i18n/locales/hi-IN.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "{{name}} से नया संदेश: {{message}}", "A11y_incoming_call_dismiss": "खारिज करें", "A11y_incoming_call_swipe_down_to_view_options": "विकल्प देखने के लिए नीचे स्वाइप करें", + "ABAC_disabled_action_reason": "ABAC-प्रबंधित कमरों में उपलब्ध नहीं है", + "ABAC_managed": "ABAC प्रबंधित", + "ABAC_managed_description": "केवल संगत उपयोगकर्ताओं के पास विशेषता-आधारित पहुँच नियंत्रित कमरों तक पहुँच है। विशेषताएँ कमरे तक पहुँच निर्धारित करती हैं।", "abac_removed_user_from_the_room": "ABAC द्वारा हटाया गया", + "ABAC_room_attributes": "कमरे के गुण", "accept": "स्वीकार करें", "Accessibility": "प्रवेशयोग्यता", "Accessibility_and_Appearance": "प्रवेशयोग्यता और दृश्यता", diff --git a/app/i18n/locales/hu.json b/app/i18n/locales/hu.json index b6b1ec09c5c..ea817617994 100644 --- a/app/i18n/locales/hu.json +++ b/app/i18n/locales/hu.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Új üzenet érkezett {{name}}-tól: {{message}}", "A11y_incoming_call_dismiss": "Elutasítás", "A11y_incoming_call_swipe_down_to_view_options": "Húzza lefelé az opciók megtekintéséhez", + "ABAC_disabled_action_reason": "Nem érhető el ABAC által kezelt szobákban", + "ABAC_managed": "ABAC által kezelt", + "ABAC_managed_description": "Csak a megfelelő felhasználók férhetnek hozzá az attribútum alapú hozzáférés-vezérelt szobákhoz. Az attribútumok határozzák meg a szoba hozzáférését.", "abac_removed_user_from_the_room": "eltávolítva az ABAC által", + "ABAC_room_attributes": "Szoba attribútumok", "accept": "Elfogadom", "Accessibility": "Akadálymentesség", "Accessibility_and_Appearance": "Hozzáférhetőség és megjelenés", diff --git a/app/i18n/locales/it.json b/app/i18n/locales/it.json index 0f48f43cba6..4ebe2e05f98 100644 --- a/app/i18n/locales/it.json +++ b/app/i18n/locales/it.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Nuovo messaggio da {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Ignora", "A11y_incoming_call_swipe_down_to_view_options": "Scorri verso il basso per visualizzare le opzioni", + "ABAC_disabled_action_reason": "Non disponibile nelle stanze gestite da ABAC", + "ABAC_managed": "Gestito da ABAC", + "ABAC_managed_description": "Solo gli utenti conformi hanno accesso alle stanze controllate da accesso basato su attributi. Gli attributi determinano l'accesso alla stanza.", "abac_removed_user_from_the_room": "è stato rimosso da ABAC", + "ABAC_room_attributes": "Attributi della stanza", "Accessibility": "Accessibilità", "Accessibility_and_Appearance": "Accessibilità e aspetto", "Accessibility_statement": "Dichiarazione di accessibilità", diff --git a/app/i18n/locales/ja.json b/app/i18n/locales/ja.json index 54006a2c665..73fb86882a3 100644 --- a/app/i18n/locales/ja.json +++ b/app/i18n/locales/ja.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "{{name}} からの新しいメッセージ: {{message}}", "A11y_incoming_call_dismiss": "閉じる", "A11y_incoming_call_swipe_down_to_view_options": "オプションを見るには下にスワイプしてください", + "ABAC_disabled_action_reason": "ABAC管理の部屋では利用できません", + "ABAC_managed": "ABAC管理", + "ABAC_managed_description": "準拠しているユーザーのみが属性ベースのアクセス制御された部屋にアクセスできます。属性によって部屋へのアクセスが決まります。", "abac_removed_user_from_the_room": "ABACによって削除されました", + "ABAC_room_attributes": "部屋の属性", "Accessibility": "アクセシビリティ", "Accessibility_and_Appearance": "アクセシビリティと外観", "Accessibility_statement": "アクセシビリティ声明", diff --git a/app/i18n/locales/nl.json b/app/i18n/locales/nl.json index 784d7f4932a..1a67d012528 100644 --- a/app/i18n/locales/nl.json +++ b/app/i18n/locales/nl.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "Nieuw bericht van {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Afwijzen", "A11y_incoming_call_swipe_down_to_view_options": "Veeg omlaag om opties te bekijken", + "ABAC_disabled_action_reason": "Niet beschikbaar in ABAC-beheerde kamers", + "ABAC_managed": "ABAC beheerd", + "ABAC_managed_description": "Alleen conforme gebruikers hebben toegang tot op attributen gebaseerde toegangsgecontroleerde kamers. Attributen bepalen de toegang tot de kamer.", "abac_removed_user_from_the_room": "werd verwijderd door ABAC", + "ABAC_room_attributes": "Kamerattributen", "Accessibility": "Toegankelijkheid", "Accessibility_and_Appearance": "Toegankelijkheid & uiterlijk", "Accessibility_statement": "Toegankelijkheidsverklaring", diff --git a/app/i18n/locales/nn.json b/app/i18n/locales/nn.json index f14bacb8020..562ecd857f1 100644 --- a/app/i18n/locales/nn.json +++ b/app/i18n/locales/nn.json @@ -7,7 +7,11 @@ "A11y_in_app_notification": "Ny melding frå {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Avslå", "A11y_incoming_call_swipe_down_to_view_options": "Sveip ned for å sjå alternativa", + "ABAC_disabled_action_reason": "Ikkje tilgjengeleg i ABAC-administrerte rom", + "ABAC_managed": "ABAC-administrert", + "ABAC_managed_description": "Berre kompatible brukarar har tilgang til attributtbaserte tilgangskontrollerte rom. Attributta bestemmer romtilgangen.", "abac_removed_user_from_the_room": "vart fjerna av ABAC", + "ABAC_room_attributes": "Romattributt", "accept": "Aksepter", "Accessibility": "Tilgjengelighet", "Accessibility_and_Appearance": "Tilgjengelighet og utseende", diff --git a/app/i18n/locales/no.json b/app/i18n/locales/no.json index 854d2a1e202..354d68ad221 100644 --- a/app/i18n/locales/no.json +++ b/app/i18n/locales/no.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Ny melding fra {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Avvis", "A11y_incoming_call_swipe_down_to_view_options": "Dra ned for å se alternativer", + "ABAC_disabled_action_reason": "Ikke tilgjengelig i ABAC-administrerte rom", + "ABAC_managed": "ABAC-administrert", + "ABAC_managed_description": "Kun kompatible brukere har tilgang til attributtbaserte tilgangskontrollerte rom. Attributter bestemmer romtilgang.", "abac_removed_user_from_the_room": "ble fjernet av ABAC", + "ABAC_room_attributes": "Romattributter", "accept": "Aksepter", "Accessibility": "Tilgjengelighet", "Accessibility_and_Appearance": "Tilgjengelighet og utseende", @@ -942,5 +946,6 @@ "Your_invite_link_will_never_expire": "Invitasjonslenken din vil aldri utløpe.", "Your_password_is": "Passordet ditt er", "Your_Password_Must_Have": "Passordet ditt må inneholde:", - "Your_push_was_sent_to_s_devices": "Din push ble sendt til {{s}} enheter" + "Your_push_was_sent_to_s_devices": "Din push ble sendt til {{s}} enheter", + "Your_workspace": "Arbeidsområdet ditt" } \ No newline at end of file diff --git a/app/i18n/locales/pt-BR.json b/app/i18n/locales/pt-BR.json index a633bd118b4..ac68077fe5f 100644 --- a/app/i18n/locales/pt-BR.json +++ b/app/i18n/locales/pt-BR.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Nova mensagem de {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dispensar", "A11y_incoming_call_swipe_down_to_view_options": "Deslize para baixo para ver as opções", + "ABAC_disabled_action_reason": "Não disponível em salas gerenciadas por ABAC", + "ABAC_managed": "Gerenciado por ABAC", + "ABAC_managed_description": "Apenas usuários compatíveis têm acesso a salas controladas por acesso baseado em atributos. Atributos determinam o acesso à sala.", "abac_removed_user_from_the_room": "foi removido pelo ABAC", + "ABAC_room_attributes": "Atributos da sala", "accept": "Aceitar", "Accessibility": "Acessibilidade", "Accessibility_and_Appearance": "Acessibilidade e aparência", diff --git a/app/i18n/locales/pt-PT.json b/app/i18n/locales/pt-PT.json index 9392036e3bf..53ed358d6a7 100644 --- a/app/i18n/locales/pt-PT.json +++ b/app/i18n/locales/pt-PT.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "Nova mensagem de {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dispensar", "A11y_incoming_call_swipe_down_to_view_options": "Deslize para baixo para ver as opções.", + "ABAC_disabled_action_reason": "Não disponível em salas geridas por ABAC", + "ABAC_managed": "Gerido por ABAC", + "ABAC_managed_description": "Apenas utilizadores compatíveis têm acesso a salas controladas por acesso baseado em atributos. Atributos determinam o acesso à sala.", "abac_removed_user_from_the_room": "foi removido pelo ABAC", + "ABAC_room_attributes": "Atributos da sala", "Accessibility": "Acessibilidade", "Accessibility_and_Appearance": "Acessibilidade e aparência", "Accessibility_statement": "Declaração de acessibilidade", diff --git a/app/i18n/locales/ru.json b/app/i18n/locales/ru.json index 9be29162986..972fb82f230 100644 --- a/app/i18n/locales/ru.json +++ b/app/i18n/locales/ru.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Новое сообщение от {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Отклонить", "A11y_incoming_call_swipe_down_to_view_options": "Проведите вниз, чтобы просмотреть варианты действий", + "ABAC_disabled_action_reason": "Недоступно в комнатах, управляемых ABAC", + "ABAC_managed": "Управляется ABAC", + "ABAC_managed_description": "Только соответствующие пользователи имеют доступ к комнатам с атрибутивным контролем доступа. Атрибуты определяют доступ к комнате.", "abac_removed_user_from_the_room": "был удалён ABAC'ом", + "ABAC_room_attributes": "Атрибуты комнаты", "Accessibility": "Доступность", "Accessibility_and_Appearance": "Доступность и внешний вид", "Accessibility_statement": "Заявление о доступности", diff --git a/app/i18n/locales/sl-SI.json b/app/i18n/locales/sl-SI.json index dcbf3aeaff3..a466b3943a4 100644 --- a/app/i18n/locales/sl-SI.json +++ b/app/i18n/locales/sl-SI.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Novo sporočilo od {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Opusti", "A11y_incoming_call_swipe_down_to_view_options": "Podrsnite navzdol za ogled možnosti", + "ABAC_disabled_action_reason": "Ni na voljo v sobah, ki jih upravlja ABAC", + "ABAC_managed": "ABAC upravljano", + "ABAC_managed_description": "Samo skladni uporabniki imajo dostop do sob z nadzorom dostopa na podlagi atributov. Atributi določajo dostop do sobe.", "abac_removed_user_from_the_room": "je bil odstranjen s strani ABAC", + "ABAC_room_attributes": "Atributi sobe", "Accessibility": "Dostopnost", "Accessibility_and_Appearance": "Dostopnost in videz", "Accessibility_statement": "Izjava o dostopnosti", diff --git a/app/i18n/locales/sv.json b/app/i18n/locales/sv.json index a19bfde9387..f7363d8516e 100644 --- a/app/i18n/locales/sv.json +++ b/app/i18n/locales/sv.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "Nytt meddelande från {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Avvisa", "A11y_incoming_call_swipe_down_to_view_options": "Svep nedåt för att se alternativ", + "ABAC_disabled_action_reason": "Inte tillgängligt i ABAC-hanterade rum", + "ABAC_managed": "ABAC-hanterat", + "ABAC_managed_description": "Endast kompatibla användare har åtkomst till attributbaserat åtkomstskyddade rum. Attributen avgör tillgången till rummet.", "abac_removed_user_from_the_room": "togs bort av ABAC", + "ABAC_room_attributes": "Rumsattribut", "Accessibility": "Tillgänglighet", "Accessibility_and_Appearance": "Tillgänglighet och utseende", "Accessibility_statement": "Tillgänglighetsredogörelse", diff --git a/app/i18n/locales/ta-IN.json b/app/i18n/locales/ta-IN.json index d33cc035f80..006cf7d6c6d 100644 --- a/app/i18n/locales/ta-IN.json +++ b/app/i18n/locales/ta-IN.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "{{name}}-இருந்து புதிய செய்தி: {{message}}", "A11y_incoming_call_dismiss": "தள்ளு", "A11y_incoming_call_swipe_down_to_view_options": "விருப்பங்களைப் பார்க்க கீழே நகர்த்தவும்", + "ABAC_disabled_action_reason": "ABAC-நிர்வகிக்கப்படும் அறைகளில் கிடைக்காது", + "ABAC_managed": "ABAC நிர்வகிக்கப்பட்டது", + "ABAC_managed_description": "இணக்கமான பயனர்கள் மட்டுமே பண்பு அடிப்படையிலான அணுகல் கட்டுப்படுத்தப்பட்ட அறைகளுக்கு அணுகல் கொண்டுள்ளனர். பண்புகள் அறை அணுகலை தீர்மானிக்கின்றன.", "abac_removed_user_from_the_room": "ABAC மூலம் அகற்றப்பட்டது", + "ABAC_room_attributes": "அறை பண்புகள்", "accept": "ஏற்றுக்கொள்", "Accessibility": "அணுகல் மேம்பாடு", "Accessibility_and_Appearance": "நுகர்வுத்திறன் மற்றும் தோற்றம்", diff --git a/app/i18n/locales/te-IN.json b/app/i18n/locales/te-IN.json index 39f56d3e6e4..1275b8352d6 100644 --- a/app/i18n/locales/te-IN.json +++ b/app/i18n/locales/te-IN.json @@ -12,7 +12,11 @@ "A11y_in_app_notification": "{{name}} నుండి కొత్త సందేశం: {{message}}", "A11y_incoming_call_dismiss": "ఖారు చేయండి", "A11y_incoming_call_swipe_down_to_view_options": "క్రిందికి స్వైప్ చేయి, పరామితులను చూడండి", + "ABAC_disabled_action_reason": "ABAC-నిర్వహించబడే గదులలో అందుబాటులో లేదు", + "ABAC_managed": "ABAC నిర్వహించబడింది", + "ABAC_managed_description": "అట్రిబ్యూట్ ఆధారిత యాక్సెస్ నియంత్రిత గదులకు అనుకూలమైన వినియోగదారులు మాత్రమే ప్రాప్యతను కలిగి ఉంటారు. లక్షణాలు గది ప్రాప్యతను నిర్ణయిస్తాయి.", "abac_removed_user_from_the_room": "ABAC ద్వారా తొలగించబడింది", + "ABAC_room_attributes": "గది లక్షణాలు", "accept": "అంగీకరించు", "Accessibility": "एक्सेसिबिलिटी", "Accessibility_and_Appearance": "प्रवेशयोग्यता और रूपरेखा", diff --git a/app/i18n/locales/tr.json b/app/i18n/locales/tr.json index a49577e72ac..92312fa9e3c 100644 --- a/app/i18n/locales/tr.json +++ b/app/i18n/locales/tr.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "Yeni mesaj {{name}}: {{message}}", "A11y_incoming_call_dismiss": "Dismiss et.", "A11y_incoming_call_swipe_down_to_view_options": "Aşağı kaydırarak seçenekleri görüntüle", + "ABAC_disabled_action_reason": "ABAC tarafından yönetilen odalarda mevcut değil", + "ABAC_managed": "ABAC tarafından yönetilir", + "ABAC_managed_description": "Yalnızca uyumlu kullanıcılar, öznitelik tabanlı erişim kontrollü odalara erişebilir. Öznitelikler, oda erişimini belirler.", "abac_removed_user_from_the_room": "ABAC tarafından kaldırıldı", + "ABAC_room_attributes": "Oda özellikleri", "Accessibility": "Erişilebilirlik", "Accessibility_and_Appearance": "Erişilebilirlik ve görünüm", "Accessibility_statement": "Erişilebilirlik beyanı", diff --git a/app/i18n/locales/zh-CN.json b/app/i18n/locales/zh-CN.json index b98af6e2e51..0f251b54a41 100644 --- a/app/i18n/locales/zh-CN.json +++ b/app/i18n/locales/zh-CN.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "来自{{name}}的新消息:{{message}}", "A11y_incoming_call_dismiss": "关闭", "A11y_incoming_call_swipe_down_to_view_options": "向下滑动以查看选项", + "ABAC_disabled_action_reason": "在ABAC管理的房间中不可用", + "ABAC_managed": "ABAC 管理", + "ABAC_managed_description": "只有符合条件的用户才能访问基于属性的访问控制房间。属性决定房间访问权限。", "abac_removed_user_from_the_room": "被ABAC删除", + "ABAC_room_attributes": "房间属性", "Accessibility": "无障碍性", "Accessibility_and_Appearance": "辅助功能和外观", "Accessibility_statement": "无障碍声明", diff --git a/app/i18n/locales/zh-TW.json b/app/i18n/locales/zh-TW.json index e80257999eb..490c728f28e 100644 --- a/app/i18n/locales/zh-TW.json +++ b/app/i18n/locales/zh-TW.json @@ -8,7 +8,11 @@ "A11y_in_app_notification": "來自 {{name}} 的新訊息:{{message}}", "A11y_incoming_call_dismiss": "關閉", "A11y_incoming_call_swipe_down_to_view_options": "向下滑動以查看選項", + "ABAC_disabled_action_reason": "無法在 ABAC 管理的房間中使用", + "ABAC_managed": "ABAC 管理", + "ABAC_managed_description": "只有符合條件的使用者才能存取基於屬性的存取控制房間。屬性決定房間存取權限。", "abac_removed_user_from_the_room": "被ABAC刪除", + "ABAC_room_attributes": "房間屬性", "Accessibility": "無障礙設施", "Accessibility_and_Appearance": "無障礙功能與外觀", "Accessibility_statement": "无障碍声明", diff --git a/app/lib/methods/helpers/mergeSubscriptionsRooms.ts b/app/lib/methods/helpers/mergeSubscriptionsRooms.ts index 2199c023272..5cb9d7166c8 100644 --- a/app/lib/methods/helpers/mergeSubscriptionsRooms.ts +++ b/app/lib/methods/helpers/mergeSubscriptionsRooms.ts @@ -34,7 +34,11 @@ export const merge = ( mergedSubscription.jitsiTimeout = room.jitsiTimeout; mergedSubscription.usernames = room.usernames; mergedSubscription.uids = room.uids; - mergedSubscription.abacAttributes = ['Classified', 'Top Secret', 'Confidential']; // TODO: remove this once we have the actual abac attributes + mergedSubscription.abacAttributes = [ + { name: 'Chat sensitivity', values: ['Classified', 'Top Secret'] }, + { name: 'Country', values: ['US-only'] }, + { name: 'Project', values: ['F-038', 'A-072'] } + ]; // TODO: remove this once we have the actual abac attributes } if (compareServerVersion(serverVersion, 'lowerThan', '3.7.0')) { diff --git a/app/views/RoomInfoView/Channel.tsx b/app/views/RoomInfoView/Channel.tsx index ae8bdce74b9..af7f5f4d149 100644 --- a/app/views/RoomInfoView/Channel.tsx +++ b/app/views/RoomInfoView/Channel.tsx @@ -3,6 +3,7 @@ import React from 'react'; import I18n from '../../i18n'; import { type ISubscription } from '../../definitions'; import Item from './Item'; +import { RoomInfoABAC } from './components/RoomInfoABAC'; const Channel = ({ room }: { room?: ISubscription }): React.ReactElement => { const description = room?.description || `__${I18n.t('No_label_provided', { label: 'description' })}__`; @@ -15,6 +16,7 @@ const Channel = ({ room }: { room?: ISubscription }): React.ReactElement => { <Item label={I18n.t('Topic')} content={topic} testID='room-info-view-topic' /> <Item label={I18n.t('Announcement')} content={announcement} testID='room-info-view-announcement' /> <Item label={I18n.t('Broadcast')} content={broadcast} testID='room-info-view-broadcast' /> + <RoomInfoABAC abacAttributes={room?.abacAttributes} teamMain={room?.teamMain} /> </> ); }; diff --git a/app/views/RoomInfoView/Direct.tsx b/app/views/RoomInfoView/Direct.tsx index 065068d9642..40d64c203e4 100644 --- a/app/views/RoomInfoView/Direct.tsx +++ b/app/views/RoomInfoView/Direct.tsx @@ -7,6 +7,7 @@ import CustomFields from './CustomFields'; import Timezone from './Timezone'; import styles from './styles'; import { type IUser } from '../../definitions'; +import { RoomInfoTag, RoomInfoTagContainer } from './components/RoomInfoTag'; const Roles = ({ roles }: { roles?: string[] }) => { const { colors } = useTheme(); @@ -15,18 +16,11 @@ const Roles = ({ roles }: { roles?: string[] }) => { return ( <View style={styles.item} testID='user-roles'> <Text style={[styles.itemLabel, { color: colors.fontTitlesLabels }]}>{I18n.t('Roles')}</Text> - <View style={styles.rolesContainer}> + <RoomInfoTagContainer> {roles.map(role => - role ? ( - <View - style={[styles.roleBadge, { backgroundColor: colors.surfaceSelected }]} - key={role} - testID={`user-role-${role.replace(/ /g, '-')}`}> - <Text style={[styles.role, { color: colors.fontTitlesLabels }]}>{role}</Text> - </View> - ) : null + role ? <RoomInfoTag name={role} key={role} testID={`user-role-${role.replace(/ /g, '-')}`} /> : null )} - </View> + </RoomInfoTagContainer> </View> ); } diff --git a/app/views/RoomInfoView/Item.tsx b/app/views/RoomInfoView/Item.tsx index 3707c365014..45bacc9de89 100644 --- a/app/views/RoomInfoView/Item.tsx +++ b/app/views/RoomInfoView/Item.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import { Text, View } from 'react-native'; +import { View } from 'react-native'; import Markdown from '../../containers/markdown'; -import { useTheme } from '../../theme'; import styles from './styles'; +import { ItemLabel } from './components/ItemLabel'; interface IItem { label?: string; @@ -12,15 +12,11 @@ interface IItem { } const Item = ({ label, content, testID }: IItem): React.ReactElement | null => { - const { colors } = useTheme(); - if (!content) return null; return ( <View style={styles.item} testID={testID}> - <Text accessibilityLabel={label} style={[styles.itemLabel, { color: colors.fontTitlesLabels }]}> - {label} - </Text> + {label ? <ItemLabel label={label} testID={testID} /> : null} <Markdown msg={content} /> </View> ); diff --git a/app/views/RoomInfoView/components/ItemLabel.tsx b/app/views/RoomInfoView/components/ItemLabel.tsx new file mode 100644 index 00000000000..50b5c872881 --- /dev/null +++ b/app/views/RoomInfoView/components/ItemLabel.tsx @@ -0,0 +1,18 @@ +import { Text } from 'react-native'; + +import { useTheme } from '../../../theme'; +import styles from '../styles'; + +interface IItemLabel { + label: string; + testID?: string; +} + +export const ItemLabel = ({ label, testID }: IItemLabel) => { + const { colors } = useTheme(); + return ( + <Text accessibilityLabel={label} style={[styles.itemLabel, { color: colors.fontTitlesLabels }]} testID={testID}> + {label} + </Text> + ); +}; diff --git a/app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx b/app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx new file mode 100644 index 00000000000..2acc6adfe4c --- /dev/null +++ b/app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { ScrollView, View } from 'react-native'; + +import { RoomInfoABAC } from './RoomInfoABAC'; +import type { TSupportedThemes } from '../../../theme'; +import { ThemeContext } from '../../../theme'; +import { colors } from '../../../lib/constants/colors'; + +export default { + title: 'RoomInfoABAC', + component: RoomInfoABAC, + decorators: [ + (Story: any) => ( + <ScrollView> + <Story /> + </ScrollView> + ) + ] +}; + +const Story = () => ( + <> + <RoomInfoABAC abacAttributes={[{ name: 'Chat sensitivity', values: ['Classified', 'Top Secret'] }]} teamMain /> + <RoomInfoABAC + abacAttributes={[ + { name: 'Attribute', values: Array.from({ length: 10 }, (_, index) => `Value ${index + 1}`) }, + { name: 'Chat sensitivity', values: ['Classified', 'Top Secret'] } + ]} + /> + </> +); + +const ThemeProvider = ({ children, theme }: { children: React.ReactNode; theme: TSupportedThemes }) => ( + <ThemeContext.Provider value={{ theme, colors: colors[theme] }}> + <View style={{ backgroundColor: colors[theme].surfaceRoom }}>{children}</View> + </ThemeContext.Provider> +); + +export const Light = () => ( + <ThemeProvider theme='light'> + <Story /> + </ThemeProvider> +); +export const Dark = () => ( + <ThemeProvider theme='dark'> + <Story /> + </ThemeProvider> +); +export const Black = () => ( + <ThemeProvider theme='black'> + <Story /> + </ThemeProvider> +); diff --git a/app/views/RoomInfoView/components/RoomInfoABAC.test.tsx b/app/views/RoomInfoView/components/RoomInfoABAC.test.tsx new file mode 100644 index 00000000000..862228bfbd1 --- /dev/null +++ b/app/views/RoomInfoView/components/RoomInfoABAC.test.tsx @@ -0,0 +1,4 @@ +import { generateSnapshots } from '../../../../.rnstorybook/generateSnapshots'; +import * as stories from './RoomInfoABAC.stories'; + +generateSnapshots(stories); diff --git a/app/views/RoomInfoView/components/RoomInfoABAC.tsx b/app/views/RoomInfoView/components/RoomInfoABAC.tsx new file mode 100644 index 00000000000..cecf68696a9 --- /dev/null +++ b/app/views/RoomInfoView/components/RoomInfoABAC.tsx @@ -0,0 +1,48 @@ +import { Text, View } from 'react-native'; + +import * as List from '../../../containers/List'; +import styles from '../styles'; +import { RoomInfoTag, RoomInfoTagContainer } from './RoomInfoTag'; +import type { ISubscription } from '../../../definitions'; +import { ItemLabel } from './ItemLabel'; +import { useTheme } from '../../../theme'; +import I18n from '../../../i18n'; + +export const RoomInfoABAC = ({ + abacAttributes, + teamMain +}: { + abacAttributes?: ISubscription['abacAttributes']; + teamMain?: boolean; +}) => { + const { colors } = useTheme(); + + if (!abacAttributes?.length) { + return null; + } + + return ( + <View style={styles.item}> + <List.Separator style={{ marginBottom: 20 }} /> + <View style={{ gap: 16 }}> + <RoomInfoTagContainer> + <RoomInfoTag name={I18n.t('ABAC_managed')} icon={teamMain ? 'team-shield' : 'hash-shield'} /> + </RoomInfoTagContainer> + + <Text style={[styles.abacDescription, { color: colors.fontSecondaryInfo }]}>{I18n.t('ABAC_managed_description')}</Text> + + <ItemLabel label={I18n.t('ABAC_room_attributes')} /> + {abacAttributes.map(attribute => ( + <View key={attribute.name} style={{ gap: 8 }}> + <Text style={[styles.abacDescription, { color: colors.fontDefault }]}>{attribute.name}</Text> + <RoomInfoTagContainer> + {attribute.values.map(value => ( + <RoomInfoTag name={value} key={value} /> + ))} + </RoomInfoTagContainer> + </View> + ))} + </View> + </View> + ); +}; diff --git a/app/views/RoomInfoView/components/RoomInfoTag.tsx b/app/views/RoomInfoView/components/RoomInfoTag.tsx new file mode 100644 index 00000000000..a68e27ab8d5 --- /dev/null +++ b/app/views/RoomInfoView/components/RoomInfoTag.tsx @@ -0,0 +1,22 @@ +import { Text, View } from 'react-native'; +import type { ReactNode } from 'react'; + +import { useTheme } from '../../../theme'; +import styles from '../styles'; +import { CustomIcon } from '../../../containers/CustomIcon'; +import type { TIconsName } from '../../../containers/CustomIcon'; + +export const RoomInfoTag = ({ name, icon, testID }: { name: string; icon?: TIconsName; testID?: string }) => { + const { colors } = useTheme(); + + return ( + <View style={[styles.roleBadge, { backgroundColor: colors.surfaceSelected }]} testID={testID}> + {icon ? <CustomIcon name={icon} size={16} /> : null} + <Text style={[styles.role, { color: colors.buttonFontSecondary }]}>{name}</Text> + </View> + ); +}; + +export const RoomInfoTagContainer = ({ children }: { children: ReactNode }) => ( + <View style={styles.rolesContainer}>{children}</View> +); diff --git a/app/views/RoomInfoView/components/__snapshots__/RoomInfoABAC.test.tsx.snap b/app/views/RoomInfoView/components/__snapshots__/RoomInfoABAC.test.tsx.snap new file mode 100644 index 00000000000..50b4c7d7237 --- /dev/null +++ b/app/views/RoomInfoView/components/__snapshots__/RoomInfoABAC.test.tsx.snap @@ -0,0 +1,2755 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Story Snapshots: Black should match snapshot 1`] = ` +<RCTScrollView> + <View> + <View + style={ + { + "backgroundColor": "#000000", + } + } + > + <View + style={ + { + "gap": 8, + "justifyContent": "center", + "paddingHorizontal": 20, + "paddingVertical": 10, + } + } + > + <View + style={ + [ + { + "height": 0.5, + }, + { + "marginBottom": 20, + }, + { + "backgroundColor": "#1f2329", + }, + ] + } + /> + <View + style={ + { + "gap": 16, + } + } + > + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#E4E7EA", + "fontSize": 16, + }, + [ + { + "lineHeight": 16, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + ABAC managed + </Text> + </View> + </View> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#9EA2A8", + }, + ] + } + > + Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access. + </Text> + <Text + accessibilityLabel="Room attributes" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 14, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#F2F3F5", + }, + ] + } + > + Room attributes + </Text> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Chat sensitivity + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Classified + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Top Secret + </Text> + </View> + </View> + </View> + </View> + </View> + <View + style={ + { + "gap": 8, + "justifyContent": "center", + "paddingHorizontal": 20, + "paddingVertical": 10, + } + } + > + <View + style={ + [ + { + "height": 0.5, + }, + { + "marginBottom": 20, + }, + { + "backgroundColor": "#1f2329", + }, + ] + } + /> + <View + style={ + { + "gap": 16, + } + } + > + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#E4E7EA", + "fontSize": 16, + }, + [ + { + "lineHeight": 16, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + ABAC managed + </Text> + </View> + </View> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#9EA2A8", + }, + ] + } + > + Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access. + </Text> + <Text + accessibilityLabel="Room attributes" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 14, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#F2F3F5", + }, + ] + } + > + Room attributes + </Text> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Attribute + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 1 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 2 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 3 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 4 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 5 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 6 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 7 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 8 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 9 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 10 + </Text> + </View> + </View> + </View> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Chat sensitivity + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Classified + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Top Secret + </Text> + </View> + </View> + </View> + </View> + </View> + </View> + </View> +</RCTScrollView> +`; + +exports[`Story Snapshots: Dark should match snapshot 1`] = ` +<RCTScrollView> + <View> + <View + style={ + { + "backgroundColor": "#1F2329", + } + } + > + <View + style={ + { + "gap": 8, + "justifyContent": "center", + "paddingHorizontal": 20, + "paddingVertical": 10, + } + } + > + <View + style={ + [ + { + "height": 0.5, + }, + { + "marginBottom": 20, + }, + { + "backgroundColor": "#333842", + }, + ] + } + /> + <View + style={ + { + "gap": 16, + } + } + > + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#E4E7EA", + "fontSize": 16, + }, + [ + { + "lineHeight": 16, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + ABAC managed + </Text> + </View> + </View> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#9EA2A8", + }, + ] + } + > + Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access. + </Text> + <Text + accessibilityLabel="Room attributes" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 14, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#F2F3F5", + }, + ] + } + > + Room attributes + </Text> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Chat sensitivity + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Classified + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Top Secret + </Text> + </View> + </View> + </View> + </View> + </View> + <View + style={ + { + "gap": 8, + "justifyContent": "center", + "paddingHorizontal": 20, + "paddingVertical": 10, + } + } + > + <View + style={ + [ + { + "height": 0.5, + }, + { + "marginBottom": 20, + }, + { + "backgroundColor": "#333842", + }, + ] + } + /> + <View + style={ + { + "gap": 16, + } + } + > + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#E4E7EA", + "fontSize": 16, + }, + [ + { + "lineHeight": 16, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + ABAC managed + </Text> + </View> + </View> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#9EA2A8", + }, + ] + } + > + Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access. + </Text> + <Text + accessibilityLabel="Room attributes" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 14, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#F2F3F5", + }, + ] + } + > + Room attributes + </Text> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Attribute + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 1 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 2 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 3 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 4 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 5 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 6 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 7 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 8 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 9 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Value 10 + </Text> + </View> + </View> + </View> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Chat sensitivity + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Classified + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#3C3F44", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#E4E7EA", + }, + ] + } + > + Top Secret + </Text> + </View> + </View> + </View> + </View> + </View> + </View> + </View> +</RCTScrollView> +`; + +exports[`Story Snapshots: Light should match snapshot 1`] = ` +<RCTScrollView> + <View> + <View + style={ + { + "backgroundColor": "#FFFFFF", + } + } + > + <View + style={ + { + "gap": 8, + "justifyContent": "center", + "paddingHorizontal": 20, + "paddingVertical": 10, + } + } + > + <View + style={ + [ + { + "height": 0.5, + }, + { + "marginBottom": 20, + }, + { + "backgroundColor": "#CBCED1", + }, + ] + } + /> + <View + style={ + { + "gap": 16, + } + } + > + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#2F343D", + "fontSize": 16, + }, + [ + { + "lineHeight": 16, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + ABAC managed + </Text> + </View> + </View> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#6C727A", + }, + ] + } + > + Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access. + </Text> + <Text + accessibilityLabel="Room attributes" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 14, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Room attributes + </Text> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#2F343D", + }, + ] + } + > + Chat sensitivity + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Classified + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Top Secret + </Text> + </View> + </View> + </View> + </View> + </View> + <View + style={ + { + "gap": 8, + "justifyContent": "center", + "paddingHorizontal": 20, + "paddingVertical": 10, + } + } + > + <View + style={ + [ + { + "height": 0.5, + }, + { + "marginBottom": 20, + }, + { + "backgroundColor": "#CBCED1", + }, + ] + } + /> + <View + style={ + { + "gap": 16, + } + } + > + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + allowFontScaling={false} + selectable={false} + style={ + [ + { + "color": "#2F343D", + "fontSize": 16, + }, + [ + { + "lineHeight": 16, + }, + undefined, + ], + { + "fontFamily": "custom", + "fontStyle": "normal", + "fontWeight": "normal", + }, + {}, + ] + } + > +  + </Text> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + ABAC managed + </Text> + </View> + </View> + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#6C727A", + }, + ] + } + > + Only compliant users have access to attribute-based access controlled rooms. Attributes determine room access. + </Text> + <Text + accessibilityLabel="Room attributes" + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 14, + "fontWeight": "500", + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Room attributes + </Text> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#2F343D", + }, + ] + } + > + Attribute + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 1 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 2 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 3 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 4 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 5 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 6 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 7 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 8 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 9 + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Value 10 + </Text> + </View> + </View> + </View> + <View + style={ + { + "gap": 8, + } + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 16, + "fontWeight": "400", + "lineHeight": 22, + "textAlign": "left", + }, + { + "color": "#2F343D", + }, + ] + } + > + Chat sensitivity + </Text> + <View + style={ + { + "flexDirection": "row", + "flexWrap": "wrap", + "gap": 4, + } + } + > + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Classified + </Text> + </View> + <View + style={ + [ + { + "alignItems": "center", + "borderRadius": 4, + "flexDirection": "row", + "gap": 2, + "padding": 4, + }, + { + "backgroundColor": "#D7DBE0", + }, + ] + } + > + <Text + style={ + [ + { + "backgroundColor": "transparent", + "fontFamily": "Inter", + "fontSize": 12, + "fontWeight": "700", + "lineHeight": 16, + "textAlign": "left", + }, + { + "color": "#1F2329", + }, + ] + } + > + Top Secret + </Text> + </View> + </View> + </View> + </View> + </View> + </View> + </View> +</RCTScrollView> +`; diff --git a/app/views/RoomInfoView/index.tsx b/app/views/RoomInfoView/index.tsx index e0f9fa01159..76e6a355c09 100644 --- a/app/views/RoomInfoView/index.tsx +++ b/app/views/RoomInfoView/index.tsx @@ -284,7 +284,7 @@ const RoomInfoView = (): React.ReactElement => { }; return ( - <ScrollView style={[styles.scroll, { backgroundColor: colors.surfaceRoom }]}> + <ScrollView style={[styles.scroll, { backgroundColor: colors.surfaceRoom }]} contentContainerStyle={{ paddingBottom: 30 }}> <SafeAreaView style={{ backgroundColor: colors.surfaceRoom }} testID='room-info-view'> <View style={[styles.avatarContainer, { backgroundColor: colors.surfaceHover }]}> <RoomInfoViewAvatar diff --git a/app/views/RoomInfoView/styles.ts b/app/views/RoomInfoView/styles.ts index 7711e6fcb74..13b0741d5bc 100644 --- a/app/views/RoomInfoView/styles.ts +++ b/app/views/RoomInfoView/styles.ts @@ -13,7 +13,8 @@ export default StyleSheet.create({ item: { paddingVertical: 10, paddingHorizontal: 20, - justifyContent: 'center' + justifyContent: 'center', + gap: 8 }, avatarContainer: { minHeight: 320, @@ -48,7 +49,6 @@ export default StyleSheet.create({ alignItems: 'center' }, itemLabel: { - marginBottom: 10, fontSize: 14, ...sharedStyles.textMedium }, @@ -61,17 +61,20 @@ export default StyleSheet.create({ }, rolesContainer: { flexDirection: 'row', - flexWrap: 'wrap' + flexWrap: 'wrap', + gap: 4 }, roleBadge: { - padding: 6, - borderRadius: 4, - marginRight: 6, - marginBottom: 6 + flexDirection: 'row', + alignItems: 'center', + gap: 2, + padding: 4, + borderRadius: 4 }, role: { - fontSize: 14, - ...sharedStyles.textRegular + fontSize: 12, + lineHeight: 16, + ...sharedStyles.textBold }, roomButtonsContainer: { flexDirection: 'row', @@ -90,5 +93,10 @@ export default StyleSheet.create({ paddingTop: 16, paddingHorizontal: 20, alignItems: 'center' + }, + abacDescription: { + lineHeight: 22, + fontSize: 16, + ...sharedStyles.textRegular } }); From 43ed6b5f1bcb8886e24712b40403d963adb5a44e Mon Sep 17 00:00:00 2001 From: Diego Mello <diegolmello@gmail.com> Date: Wed, 17 Dec 2025 13:18:38 -0300 Subject: [PATCH 5/6] Remove mocks and update name -> key --- app/containers/RoomHeader/RoomHeader.stories.tsx | 4 ++-- app/containers/RoomItem/RoomItem.stories.tsx | 4 ++-- app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx | 4 ++-- app/definitions/IRoom.ts | 1 + app/definitions/ISubscription.ts | 2 +- app/lib/methods/helpers/mergeSubscriptionsRooms.ts | 9 ++++----- .../RoomInfoView/components/RoomInfoABAC.stories.tsx | 6 +++--- app/views/RoomInfoView/components/RoomInfoABAC.tsx | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/containers/RoomHeader/RoomHeader.stories.tsx b/app/containers/RoomHeader/RoomHeader.stories.tsx index 2372e1bd305..00c7252ec46 100644 --- a/app/containers/RoomHeader/RoomHeader.stories.tsx +++ b/app/containers/RoomHeader/RoomHeader.stories.tsx @@ -57,7 +57,7 @@ export const Icons = () => ( <HeaderExample title={() => <RoomHeader title='offline dm' type='d' />} /> <HeaderExample title={() => ( - <RoomHeader title='classified' type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> + <RoomHeader title='classified' type='p' abacAttributes={[{ key: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> )} /> <HeaderExample @@ -65,7 +65,7 @@ export const Icons = () => ( <RoomHeader title='classified' type='p' - abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} + abacAttributes={[{ key: 'Attribute', values: ['Value 1', 'Value 2'] }]} teamMain /> )} diff --git a/app/containers/RoomItem/RoomItem.stories.tsx b/app/containers/RoomItem/RoomItem.stories.tsx index 074ede08b2c..a6c392b8345 100644 --- a/app/containers/RoomItem/RoomItem.stories.tsx +++ b/app/containers/RoomItem/RoomItem.stories.tsx @@ -71,8 +71,8 @@ export const Type = () => ( <RoomItem type='l' /> <RoomItem type='discussion' /> <RoomItem type='d' isGroupChat /> - <RoomItem type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> - <RoomItem type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} teamMain /> + <RoomItem type='p' abacAttributes={[{ key: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> + <RoomItem type='p' abacAttributes={[{ key: 'Attribute', values: ['Value 1', 'Value 2'] }]} teamMain /> <RoomItem type='&' /> </> ); diff --git a/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx b/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx index 3e731182bab..07b425f9634 100644 --- a/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx +++ b/app/containers/RoomTypeIcon/RoomTypeIcon.stories.tsx @@ -18,8 +18,8 @@ export const All = () => ( <RoomTypeIcon size={30} type='p' teamMain /> <RoomTypeIcon size={30} type='discussion' /> <RoomTypeIcon size={30} type='l' status='away' sourceType={{ type: OmnichannelSourceType.SMS }} /> - <RoomTypeIcon size={30} type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> - <RoomTypeIcon size={30} type='p' abacAttributes={[{ name: 'Attribute', values: ['Value 1', 'Value 2'] }]} teamMain /> + <RoomTypeIcon size={30} type='p' abacAttributes={[{ key: 'Attribute', values: ['Value 1', 'Value 2'] }]} /> + <RoomTypeIcon size={30} type='p' abacAttributes={[{ key: 'Attribute', values: ['Value 1', 'Value 2'] }]} teamMain /> <RoomTypeIcon size={30} type='p' style={{ margin: 10 }} /> </> ); diff --git a/app/definitions/IRoom.ts b/app/definitions/IRoom.ts index 64f0b8eb87e..ef936a8e7b8 100644 --- a/app/definitions/IRoom.ts +++ b/app/definitions/IRoom.ts @@ -233,6 +233,7 @@ export interface IServerRoom extends IRocketChatRecord { isLastOwner?: boolean; federated?: boolean; + abacAttributes?: { key: string; values: string[] }[]; } export interface IRoomNotifications { diff --git a/app/definitions/ISubscription.ts b/app/definitions/ISubscription.ts index 0c7bc2b7262..cbeff295b76 100644 --- a/app/definitions/ISubscription.ts +++ b/app/definitions/ISubscription.ts @@ -116,7 +116,7 @@ export interface ISubscription { uploads: RelationModified<TUploadModel>; disableNotifications?: boolean; federated?: boolean; - abacAttributes?: { name: string; values: string[] }[]; + abacAttributes?: { key: string; values: string[] }[]; } export type TSubscriptionModel = ISubscription & diff --git a/app/lib/methods/helpers/mergeSubscriptionsRooms.ts b/app/lib/methods/helpers/mergeSubscriptionsRooms.ts index 5cb9d7166c8..99431759657 100644 --- a/app/lib/methods/helpers/mergeSubscriptionsRooms.ts +++ b/app/lib/methods/helpers/mergeSubscriptionsRooms.ts @@ -14,6 +14,7 @@ import { } from '../../../definitions'; import { compareServerVersion } from './compareServerVersion'; +// eslint-disable-next-line complexity export const merge = ( subscription: ISubscription | IServerSubscription, room?: IRoom | IServerRoom | IOmnichannelRoom @@ -34,11 +35,6 @@ export const merge = ( mergedSubscription.jitsiTimeout = room.jitsiTimeout; mergedSubscription.usernames = room.usernames; mergedSubscription.uids = room.uids; - mergedSubscription.abacAttributes = [ - { name: 'Chat sensitivity', values: ['Classified', 'Top Secret'] }, - { name: 'Country', values: ['US-only'] }, - { name: 'Project', values: ['F-038', 'A-072'] } - ]; // TODO: remove this once we have the actual abac attributes } if (compareServerVersion(serverVersion, 'lowerThan', '3.7.0')) { @@ -69,6 +65,9 @@ export const merge = ( mergedSubscription.teamId = room?.teamId; mergedSubscription.teamMain = room?.teamMain; mergedSubscription.federated = room?.federated; + if (room && 'abacAttributes' in room) { + mergedSubscription.abacAttributes = room.abacAttributes || []; + } if (!mergedSubscription.roles || !mergedSubscription.roles.length) { mergedSubscription.roles = []; } diff --git a/app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx b/app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx index 2acc6adfe4c..56e79d09175 100644 --- a/app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx +++ b/app/views/RoomInfoView/components/RoomInfoABAC.stories.tsx @@ -20,11 +20,11 @@ export default { const Story = () => ( <> - <RoomInfoABAC abacAttributes={[{ name: 'Chat sensitivity', values: ['Classified', 'Top Secret'] }]} teamMain /> + <RoomInfoABAC abacAttributes={[{ key: 'Chat sensitivity', values: ['Classified', 'Top Secret'] }]} teamMain /> <RoomInfoABAC abacAttributes={[ - { name: 'Attribute', values: Array.from({ length: 10 }, (_, index) => `Value ${index + 1}`) }, - { name: 'Chat sensitivity', values: ['Classified', 'Top Secret'] } + { key: 'Attribute', values: Array.from({ length: 10 }, (_, index) => `Value ${index + 1}`) }, + { key: 'Chat sensitivity', values: ['Classified', 'Top Secret'] } ]} /> </> diff --git a/app/views/RoomInfoView/components/RoomInfoABAC.tsx b/app/views/RoomInfoView/components/RoomInfoABAC.tsx index cecf68696a9..4eaf8a85cb2 100644 --- a/app/views/RoomInfoView/components/RoomInfoABAC.tsx +++ b/app/views/RoomInfoView/components/RoomInfoABAC.tsx @@ -33,8 +33,8 @@ export const RoomInfoABAC = ({ <ItemLabel label={I18n.t('ABAC_room_attributes')} /> {abacAttributes.map(attribute => ( - <View key={attribute.name} style={{ gap: 8 }}> - <Text style={[styles.abacDescription, { color: colors.fontDefault }]}>{attribute.name}</Text> + <View key={attribute.key} style={{ gap: 8 }}> + <Text style={[styles.abacDescription, { color: colors.fontDefault }]}>{attribute.key}</Text> <RoomInfoTagContainer> {attribute.values.map(value => ( <RoomInfoTag name={value} key={value} /> From bfa0e07dfea113745d6005f8c8d8d96c96826be7 Mon Sep 17 00:00:00 2001 From: Diego Mello <diegolmello@gmail.com> Date: Mon, 22 Dec 2025 16:49:55 -0300 Subject: [PATCH 6/6] feat: enhance ListItem and ActionsSection with disabled state handling - Added `disabledReason` prop to IListItemButton and IListItemContent interfaces. - Implemented event emission for disabled buttons in ListItem. - Updated ActionsSection to conditionally disable the invite user action based on ABAC attributes. --- app/containers/List/ListItem.tsx | 26 ++++++++++++++++--- .../components/ActionsSection.tsx | 4 ++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/containers/List/ListItem.tsx b/app/containers/List/ListItem.tsx index 09985caf37b..696ec0c17b1 100644 --- a/app/containers/List/ListItem.tsx +++ b/app/containers/List/ListItem.tsx @@ -18,6 +18,8 @@ import { Icon } from '.'; import { BASE_HEIGHT, ICON_SIZE, PADDING_HORIZONTAL } from './constants'; import { CustomIcon } from '../CustomIcon'; import { useResponsiveLayout } from '../../lib/hooks/useResponsiveLayout/useResponsiveLayout'; +import EventEmitter from '../../lib/methods/helpers/events'; +import { LISTENER } from '../Toast'; const styles = StyleSheet.create({ container: { @@ -90,6 +92,7 @@ interface IListItemContent { left?: () => JSX.Element | null; right?: () => JSX.Element | null; disabled?: boolean; + disabledReason?: string; testID?: string; color?: string; translateTitle?: boolean; @@ -154,7 +157,15 @@ const Content = React.memo( } } return label; - }, [title, subtitle, translateTitle, translateSubtitle, additionalAcessibilityLabel, additionalAcessibilityLabelCheck]); + }, [ + accessibilityLabel, + title, + subtitle, + translateTitle, + translateSubtitle, + additionalAcessibilityLabel, + additionalAcessibilityLabelCheck + ]); return ( <View @@ -205,6 +216,7 @@ interface IListButtonPress extends IListItemButton { interface IListItemButton { title: string | (() => JSX.Element | null); disabled?: boolean; + disabledReason?: string; backgroundColor?: string; underlayColor?: string; } @@ -214,12 +226,20 @@ const Button = React.memo(({ onPress, backgroundColor, underlayColor, ...props } const { colors } = useTheme(); + const handlePress = () => { + if (props.disabled && props.disabledReason) { + EventEmitter.emit(LISTENER, { message: props.disabledReason }); + } else if (!props.disabled) { + onPress(props.title); + } + }; + return ( <Touch - onPress={() => onPress(props.title)} + onPress={handlePress} style={{ backgroundColor: backgroundColor || colors.surfaceRoom }} underlayColor={underlayColor} - enabled={!props.disabled}> + enabled={!props.disabled || !!props.disabledReason}> <Content {...props} /> </Touch> ); diff --git a/app/views/RoomMembersView/components/ActionsSection.tsx b/app/views/RoomMembersView/components/ActionsSection.tsx index 5a831fb5623..8fb5a74b91d 100644 --- a/app/views/RoomMembersView/components/ActionsSection.tsx +++ b/app/views/RoomMembersView/components/ActionsSection.tsx @@ -90,7 +90,7 @@ export default function ActionsSection({ rid, t, joined, abacAttributes }: IActi </> ) : null} - {['c', 'p'].includes(t) && canInviteUser && !abacAttributes ? ( + {['c', 'p'].includes(t) && canInviteUser ? ( <> <List.Item title='Invite_users' @@ -103,6 +103,8 @@ export default function ActionsSection({ rid, t, joined, abacAttributes }: IActi testID='room-actions-invite-user' left={() => <List.Icon name='user-add' />} showActionIndicator + disabled={!!abacAttributes} + disabledReason={abacAttributes ? i18n.t('ABAC_disabled_action_reason') : undefined} /> <List.Separator /> </>