20.diff (12742B)
1 diff --git a/changelog.d/20.misc b/changelog.d/20.misc 2 new file mode 100644 3 index 0000000..70d9098 4 --- /dev/null 5 +++ b/changelog.d/20.misc 6 @@ -0,0 +1 @@ 7 +Converting the flex layout to a flatter grid layout. 8 \ No newline at end of file 9 diff --git a/src/components/avatar/avatar.tsx b/src/components/avatar/avatar.tsx 10 index f154e99..3777e10 100644 11 --- a/src/components/avatar/avatar.tsx 12 +++ b/src/components/avatar/avatar.tsx 13 @@ -30,7 +30,7 @@ const Avatar: FC<AvatarProps> = memo(({ avatarUrl, displayname, dm = false, onli 14 15 if (avatarUrl && !error) { 16 return ( 17 - <div className="flex relative min-w-[2rem] min-h-[2rem] w-[2rem] h-[2rem] justify-center items-center m-0 mr-3 text-xl rounded-full text-white"> 18 + <div className="flex relative min-w-[2rem] min-h-[2rem] w-[2rem] h-[2rem] justify-center items-center text-xl rounded-full text-white"> 19 <img className="rounded-full w-8 h-8 object-cover" alt={displayname} src={avatarUrl} onError={() => { setError(true) }} /> 20 { 21 dm ? 22 diff --git a/src/components/input/chat/input.scss b/src/components/input/chat/input.scss 23 index 57bfc92..4d665d6 100644 24 --- a/src/components/input/chat/input.scss 25 +++ b/src/components/input/chat/input.scss 26 @@ -2,6 +2,7 @@ 27 @apply text-black relative font-normal; 28 line-height: 20px; 29 text-align: left; 30 + height: 100%; 31 } 32 33 .editor-inner { 34 diff --git a/src/components/input/chat/input.tsx b/src/components/input/chat/input.tsx 35 index e1f155f..a4dbb10 100644 36 --- a/src/components/input/chat/input.tsx 37 +++ b/src/components/input/chat/input.tsx 38 @@ -81,6 +81,7 @@ type ChatInputProps = { 39 * The current Room 40 */ 41 room: Room 42 + id?: string 43 }; 44 45 function Placeholder() { 46 @@ -265,7 +266,7 @@ const RoomChangePlugin: FC<RoomChangeProps> = ({ room }) => { 47 return <></> 48 } 49 50 -const ChatInput: FC<ChatInputProps> = memo(({ namespace, room }: ChatInputProps) => { 51 +const ChatInput: FC<ChatInputProps> = memo(({ namespace, room, id }: ChatInputProps) => { 52 const [sending, setSending] = useState(false); 53 54 const initialConfig: InitialConfigType = { 55 @@ -295,7 +296,7 @@ const ChatInput: FC<ChatInputProps> = memo(({ namespace, room }: ChatInputProps) 56 ] 57 } 58 return ( 59 - <div className='flex flex-row items-end'> 60 + <div id={id} className='flex flex-row items-end'> 61 <LexicalComposer initialConfig={initialConfig}> 62 <div className="editor-container flex-1"> 63 <ToolbarPlugin /> 64 diff --git a/src/components/roomList/roomList.scss b/src/components/roomList/roomList.scss 65 index 4e58c71..68a6353 100644 66 --- a/src/components/roomList/roomList.scss 67 +++ b/src/components/roomList/roomList.scss 68 @@ -14,4 +14,23 @@ 69 background-color: rgba(155, 155, 155, 0.5); 70 border-radius: 5px; 71 border: transparent; 72 +} 73 + 74 +#roomlist { 75 + @apply p-2 px-4 overflow-y-auto overflow-x-hidden scrollbarSmall gap-1; 76 + grid-area: roomlist; 77 + display: flex; 78 + flex-direction: column; 79 + flex-wrap: nowrap; 80 + align-items: flex-start; 81 + justify-content: flex-start; 82 + height: 100%; 83 + 84 + .room-section { 85 + user-select: none; 86 + display: flex; 87 + flex-direction: column; 88 + width: 100%; 89 + row-gap: 0.5rem; 90 + } 91 } 92 \ No newline at end of file 93 diff --git a/src/components/roomList/roomList.tsx b/src/components/roomList/roomList.tsx 94 index f8a8ac3..07a2066 100644 95 --- a/src/components/roomList/roomList.tsx 96 +++ b/src/components/roomList/roomList.tsx 97 @@ -135,7 +135,7 @@ const RoomSection: FC<{ section: Section, onRoomClick: (roomID: string) => void, 98 } 99 }, [hidden]) 100 return ( 101 - <div ref={ref} key={section.roomID} className="flex flex-col gap-1 pl-4 select-none"> 102 + <div ref={ref} key={section.roomID} className='room-section'> 103 { 104 inView && <div className="flex flex-row gap-2 py-1 items-center justify-start cursor-pointer h-8 text-slate-600" onClick={() => setHidden(prev => !prev)}> 105 {hidden ? <ChevronRight size={14} /> : <ChevronDown size={14} />} 106 @@ -169,7 +169,7 @@ const RoomList: FC<RoomListProps> = memo(({ sections, rooms, dmRooms }: RoomList 107 const navigate = useNavigate(); 108 109 return ( 110 - <div className="flex flex-col gap-1 flex-1 p-2 min-w-[30ch] overflow-y-auto overflow-x-hidden scrollbarSmall max-w-[33ch]"> 111 + <div id='roomlist'> 112 <RoomSection 113 section={{ 114 sectionName: "DMs", 115 diff --git a/src/components/roomList/roomListItem/roomListItem.tsx b/src/components/roomList/roomListItem/roomListItem.tsx 116 index 9157932..1883d36 100644 117 --- a/src/components/roomList/roomListItem/roomListItem.tsx 118 +++ b/src/components/roomList/roomListItem/roomListItem.tsx 119 @@ -58,12 +58,12 @@ const RoomListItem: FC<RoomListItemProps> = memo(({ roomId, avatarUrl, displayna 120 { 121 inView && (active ? ( 122 <div className="flex flex-row gap-2 p-1 bg-gray-300 hover:bg-gray-400 rounded-lg duration-200 ease-in-out items-center"> 123 - <Avatar avatarUrl={avatarUrl} displayname={displayname} dm={dm} online={online} /> 124 + <Avatar avatarUrl={avatarUrl} displayname={displayname} dm={dm} online={online} isBot={false} /> 125 <span title={displayname} className='text-slate-900 font-normal text-base max-w-[32ch] overflow-hidden text-ellipsis w-full whitespace-nowrap'>{displayname}</span> 126 </div> 127 ) : ( 128 <div className="flex flex-row gap-2 p-1 hover:bg-gray-300 rounded-lg duration-200 ease-in-out items-center"> 129 - <Avatar avatarUrl={avatarUrl} displayname={displayname} dm={dm} online={online} /> 130 + <Avatar avatarUrl={avatarUrl} displayname={displayname} dm={dm} online={online} isBot={false} /> 131 <span title={displayname} className='text-slate-900 font-normal text-base max-w-[32ch] overflow-hidden text-ellipsis w-full whitespace-nowrap'>{displayname}</span> 132 </div> 133 )) 134 diff --git a/src/index.scss b/src/index.scss 135 index a6886b2..17bb72e 100644 136 --- a/src/index.scss 137 +++ b/src/index.scss 138 @@ -44,5 +44,6 @@ pre { 139 * Blockquote should be light grey with a thick left border 140 */ 141 blockquote { 142 - @apply border-l-4 border-gray-300 p-4 py-0 bg-slate-100 rounded-md; 143 + @apply border-l-4 border-gray-300 p-4 py-0 bg-slate-100; 144 + border-radius: 0 0.375rem 0.375rem 0; 145 } 146 \ No newline at end of file 147 diff --git a/src/pages/MainPage.scss b/src/pages/MainPage.scss 148 index e69de29..ca6a3a1 100644 149 --- a/src/pages/MainPage.scss 150 +++ b/src/pages/MainPage.scss 151 @@ -0,0 +1,69 @@ 152 +#main-container { 153 + display: grid; 154 + grid-template-areas: 155 + "sidebar header" 156 + "sidebar main" 157 + "sidebar editor"; 158 + grid-template-columns: 40ch auto; 159 + grid-template-rows: 60px 2fr auto; 160 + grid-auto-flow: column; 161 + row-gap: 0.5rem; 162 + column-gap: 0.15em; 163 + 164 + #sidebar { 165 + grid-area: sidebar; 166 + @apply bg-gradient-to-br from-slate-100 via-gray-200 to-orange-200 border-r-[1px] border-slate-300; 167 + display: grid; 168 + grid-auto-flow: column; 169 + grid-template-rows: 60px auto; 170 + grid-template-areas: 171 + "user-info" 172 + "roomlist"; 173 + height: 100vh; 174 + 175 + #user-info { 176 + @apply p-3 items-center border-b-2; 177 + grid-area: user-info; 178 + column-gap: 0.5rem; 179 + display: grid; 180 + grid-auto-flow: row; 181 + grid-template-columns: auto 1fr; 182 + grid-template-areas: 183 + "avatar username"; 184 + flex-direction: row; 185 + align-items: center; 186 + justify-self: flex-start; 187 + width: 100%; 188 + 189 + #username-container { 190 + grid-area: username; 191 + display: flex; 192 + flex-direction: row; 193 + align-items: center; 194 + justify-content: space-between; 195 + } 196 + } 197 + } 198 + 199 + #room-wrapper { 200 + grid-area: header / header / editor-end / editor-end; 201 + } 202 + 203 + #room-info { 204 + @apply pb-2 border-b-2 pt-4 pl-2; 205 + display: flex; 206 + flex-direction: row; 207 + align-items: center; 208 + justify-content: start; 209 + gap: 1rem; 210 + grid-area: header; 211 + } 212 + 213 + #chat-view { 214 + grid-area: main; 215 + } 216 + 217 + #chat-editor { 218 + grid-area: editor; 219 + } 220 +} 221 \ No newline at end of file 222 diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx 223 index 3e70b8b..a6db72c 100644 224 --- a/src/pages/MainPage.tsx 225 +++ b/src/pages/MainPage.tsx 226 @@ -25,10 +25,11 @@ type ChatViewProps = { 227 * If the roomID is valid, but the room is not joined, the ChatView will display a placeholder 228 * If the roomID is valid, but the room is not loaded, the ChatView will display a placeholder 229 */ 230 - room?: Room 231 + room?: Room, 232 + id?: string 233 }; 234 235 -const ChatView: FC<ChatViewProps> = memo(({ room, }) => { 236 +const ChatView: FC<ChatViewProps> = memo(({ room, id }) => { 237 const client = useContext(MatrixContext); 238 const [events, setEvents] = useState<IRoomEvent[]>([]); 239 const [eventsFull, setEventsFull] = useState<IRoomEvent[]>([]); 240 @@ -254,6 +255,7 @@ const ChatView: FC<ChatViewProps> = memo(({ room, }) => { 241 242 return ( 243 <Virtuoso 244 + id={id} 245 alignToBottom 246 className='flex overflow-y-auto overflow-x-hidden scrollbarSmall' 247 data={events} 248 @@ -470,11 +472,11 @@ const MainPage = memo(() => { 249 className: "text-blue-500 hover:text-blue-700 active:text-blue-700 visited:text-blue-500" 250 } 251 252 - return <div className='flex flex-row gap-2 min-h-screen h-screen'> 253 - <div className='flex flex-col bg-gradient-to-br from-slate-100 via-gray-200 to-orange-200 border-r-[1px] border-slate-300'> 254 - <div className='flex flex-row gap-2 m-2 p-1 items-center border-b-2'> 255 - <Avatar displayname={profile.displayname || client.mxid!} avatarUrl={profile?.avatar_url} dm={false} online={OnlineState.Unknown} /> 256 - <div className='flex flex-row justify-between items-center w-full'> 257 + return <div id='main-container'> 258 + <div id='sidebar'> 259 + <div id="user-info"> 260 + <Avatar displayname={profile.displayname || client.mxid!} avatarUrl={profile?.avatar_url} dm={false} online={OnlineState.Unknown} isBot={false} /> 261 + <div id='username-container'> 262 <span className='text-base font-semibold'>{profile?.displayname}</span> 263 <Settings size={28} stroke='unset' className='stroke-slate-600 rounded-full hover:bg-slate-300 p-1 cursor-pointer' /> 264 </div> 265 @@ -482,19 +484,18 @@ const MainPage = memo(() => { 266 <RoomList sections={sections} rooms={otherRooms} dmRooms={dmRooms} /> 267 </div> 268 { 269 - room ? <div className='flex-1 flex flex-col' id='room-wrapper'> 270 - <div className='pb-2 flex flex-row items-center border-b-2 mt-4 ml-2'> 271 - <Avatar displayname={room.getName()} avatarUrl={room.getAvatarURL()} dm={room.isDM()} online={room.presence} /> 272 - <div className='flex flex-row items-start'> 273 - <h1 className='text-black font-semibold text-lg flex-shrink-0'>{room.getName()}</h1> 274 - <Linkify options={linkifyOptions} as='p' className="ml-4 text-slate-700 font-normal text-base line-clamp-2 text-ellipsis">{room.getTopic()}</Linkify> 275 + room ? <> 276 + <div id="room-wrapper"></div> 277 + <div id='room-info'> 278 + <Avatar displayname={room.getName()} avatarUrl={room.getAvatarURL()} dm={room.isDM()} online={room.presence} isBot={false} /> 279 + <div className='flex mr-2'> 280 + <h1 className='text-black font-semibold text-lg'>{room.getName()}</h1> 281 + <Linkify options={linkifyOptions} as='p' className="ml-2 text-slate-700 font-normal text-base line-clamp-2 text-ellipsis">{room.getTopic()}</Linkify> 282 </div> 283 </div> 284 - <div className='my-1 flex-1 flex flex-col'> 285 - <ChatView room={room} /> 286 - </div> 287 - <ChatInput namespace='Editor' room={room} /> 288 - </div> : <></> 289 + <ChatView id='chat-view' room={room} /> 290 + <ChatInput id='chat-editor' namespace='Editor' room={room} /> 291 + </> : <></> 292 } 293 </div> 294 })