mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
web/main: make room view and list separate screens on mobile
This commit is contained in:
parent
747a015bcc
commit
b31eb2ea75
5 changed files with 51 additions and 7 deletions
1
web/src/icons/back.svg
Normal file
1
web/src/icons/back.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="m313-440 224 224-57 56-320-320 320-320 57 56-224 224h487v80H313Z"/></svg>
|
After Width: | Height: | Size: 190 B |
|
@ -4,4 +4,28 @@ main.matrix-main {
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template: "roomlist roomview" 1fr / 300px 1fr;
|
grid-template: "roomlist roomview" 1fr / 300px 1fr;
|
||||||
|
|
||||||
|
@media screen and (max-width: 1000px) {
|
||||||
|
grid-template: "roomlist roomview" 1fr / 250px 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 900px) {
|
||||||
|
grid-template: "roomlist roomview" 1fr / 200px 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 750px) {
|
||||||
|
&.room-selected {
|
||||||
|
grid-template: "roomview" 1fr / 1fr;
|
||||||
|
> div.room-list-wrapper {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.room-selected) {
|
||||||
|
grid-template: "roomlist" 1fr / 1fr;
|
||||||
|
> div.room-view {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import { use, useCallback, useState } from "react"
|
import { use, useCallback, useState } from "react"
|
||||||
import type { RoomID } from "../api/types"
|
import type { RoomID } from "@/api/types"
|
||||||
import { ClientContext } from "./ClientContext.ts"
|
import { ClientContext } from "./ClientContext.ts"
|
||||||
import RoomView from "./RoomView.tsx"
|
import RoomView from "./RoomView.tsx"
|
||||||
import RoomList from "./roomlist/RoomList.tsx"
|
import RoomList from "./roomlist/RoomList.tsx"
|
||||||
|
@ -31,9 +31,10 @@ const MainScreen = () => {
|
||||||
.catch(err => console.error("Failed to load room state", err))
|
.catch(err => console.error("Failed to load room state", err))
|
||||||
}
|
}
|
||||||
}, [client])
|
}, [client])
|
||||||
return <main className="matrix-main">
|
const clearActiveRoom = useCallback(() => setActiveRoomID(null), [])
|
||||||
|
return <main className={`matrix-main ${activeRoom ? "room-selected" : ""}`}>
|
||||||
<RoomList setActiveRoom={setActiveRoom} activeRoomID={activeRoomID} />
|
<RoomList setActiveRoom={setActiveRoom} activeRoomID={activeRoomID} />
|
||||||
{activeRoom && <RoomView key={activeRoomID} room={activeRoom} />}
|
{activeRoom && <RoomView key={activeRoomID} clearActiveRoom={clearActiveRoom} room={activeRoom} />}
|
||||||
</main>
|
</main>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,26 @@ div.room-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: .5rem;
|
gap: .5rem;
|
||||||
padding-left: 1rem;
|
margin-left: .5rem;
|
||||||
border-bottom: 1px solid #ccc;
|
border-bottom: 1px solid #ccc;
|
||||||
|
|
||||||
> span.room-name {
|
> span.room-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> button.back {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
height: 2.5rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,18 @@ import { useNonNullEventAsState } from "@/util/eventdispatcher.ts"
|
||||||
import { LightboxContext } from "./Lightbox.tsx"
|
import { LightboxContext } from "./Lightbox.tsx"
|
||||||
import MessageComposer from "./MessageComposer.tsx"
|
import MessageComposer from "./MessageComposer.tsx"
|
||||||
import TimelineView from "./timeline/TimelineView.tsx"
|
import TimelineView from "./timeline/TimelineView.tsx"
|
||||||
|
import BackIcon from "@/icons/back.svg?react"
|
||||||
import "./RoomView.css"
|
import "./RoomView.css"
|
||||||
|
|
||||||
interface RoomViewProps {
|
interface RoomViewProps {
|
||||||
room: RoomStateStore
|
room: RoomStateStore
|
||||||
|
clearActiveRoom: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const RoomHeader = ({ room }: RoomViewProps) => {
|
const RoomHeader = ({ room, clearActiveRoom }: RoomViewProps) => {
|
||||||
const roomMeta = useNonNullEventAsState(room.meta)
|
const roomMeta = useNonNullEventAsState(room.meta)
|
||||||
return <div className="room-header">
|
return <div className="room-header">
|
||||||
|
<button className="back" onClick={clearActiveRoom}><BackIcon/></button>
|
||||||
<img
|
<img
|
||||||
className="avatar"
|
className="avatar"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
@ -49,12 +52,12 @@ const onKeyDownRoomView = (evt: React.KeyboardEvent) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const RoomView = ({ room }: RoomViewProps) => {
|
const RoomView = ({ room, clearActiveRoom }: RoomViewProps) => {
|
||||||
const [replyTo, setReplyTo] = useState<MemDBEvent | null>(null)
|
const [replyTo, setReplyTo] = useState<MemDBEvent | null>(null)
|
||||||
const [textRows, setTextRows] = useState(1)
|
const [textRows, setTextRows] = useState(1)
|
||||||
const closeReply = useCallback(() => setReplyTo(null), [])
|
const closeReply = useCallback(() => setReplyTo(null), [])
|
||||||
return <div className="room-view" onKeyDown={onKeyDownRoomView} tabIndex={-1}>
|
return <div className="room-view" onKeyDown={onKeyDownRoomView} tabIndex={-1}>
|
||||||
<RoomHeader room={room}/>
|
<RoomHeader room={room} clearActiveRoom={clearActiveRoom}/>
|
||||||
<TimelineView room={room} textRows={textRows} replyTo={replyTo} setReplyTo={setReplyTo}/>
|
<TimelineView room={room} textRows={textRows} replyTo={replyTo} setReplyTo={setReplyTo}/>
|
||||||
<MessageComposer room={room} setTextRows={setTextRows} replyTo={replyTo} closeReply={closeReply}/>
|
<MessageComposer room={room} setTextRows={setTextRows} replyTo={replyTo} closeReply={closeReply}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue