From 64900fbe80f3ebade8f500a067b8d7128628d528 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 27 May 2021 10:35:33 -0400 Subject: [PATCH] Implement togglable sidebars for narrow viewports Closed: https://l.sr.ht/96AD.jpg Open: https://l.sr.ht/gr_9.jpg --- components/app.js | 87 ++++++++++++++++++++++++++++++++---- style.css | 110 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 178 insertions(+), 19 deletions(-) diff --git a/components/app.js b/components/app.js index 4ccebc7..c65b320 100644 --- a/components/app.js +++ b/components/app.js @@ -166,6 +166,10 @@ export default class App extends Component { activeBuffer: null, dialog: null, error: null, + openPanels: { + bufferList: false, + memberList: false, + }, }; clients = new Map(); endOfHistory = new Map(); @@ -182,6 +186,8 @@ export default class App extends Component { this.handleConnectSubmit = this.handleConnectSubmit.bind(this); this.handleJoinSubmit = this.handleJoinSubmit.bind(this); this.handleBufferListClick = this.handleBufferListClick.bind(this); + this.toggleBufferList = this.toggleBufferList.bind(this); + this.toggleMemberList = this.toggleMemberList.bind(this); this.handleComposerSubmit = this.handleComposerSubmit.bind(this); this.handleNickClick = this.handleNickClick.bind(this); this.autocomplete = this.autocomplete.bind(this); @@ -1028,6 +1034,47 @@ export default class App extends Component { handleBufferListClick(id) { this.switchBuffer(id); + this.closeBufferList(); + } + + toggleBufferList() { + this.setState((state) => { + var openPanels = { + ...state.openPanels, + bufferList: !state.openPanels.bufferList, + }; + return { openPanels }; + }); + } + + toggleMemberList() { + this.setState((state) => { + var openPanels = { + ...state.openPanels, + memberList: !state.openPanels.memberList, + }; + return { openPanels }; + }); + } + + closeBufferList() { + this.setState((state) => { + var openPanels = { + ...state.openPanels, + bufferList: false, + }; + return { openPanels }; + }); + } + + closeMemberList() { + this.setState((state) => { + var openPanels = { + ...state.openPanels, + memberList: false, + }; + return { openPanels }; + }); } handleJoinClick(netID) { @@ -1218,14 +1265,26 @@ export default class App extends Component { var memberList = null; if (activeBuffer && activeBuffer.type == BufferType.CHANNEL) { memberList = html` -
- ${activeBuffer.members.size} users -
-
- <${MemberList} - members=${activeBuffer.members} - onNickClick=${this.handleNickClick} - /> +
+ +
+
+ ${activeBuffer.members.size} users +
+ <${MemberList} + members=${activeBuffer.members} + onNickClick=${this.handleNickClick} + /> +
`; } @@ -1272,7 +1331,10 @@ export default class App extends Component { } return html` -
+
<${BufferList} buffers=${this.state.buffers} networks=${this.state.networks} @@ -1281,6 +1343,13 @@ export default class App extends Component { activeBuffer=${this.state.activeBuffer} onBufferClick=${this.handleBufferListClick} /> +
${bufferHeader} <${ScrollManager} diff --git a/style.css b/style.css index 2ff5031..0702758 100644 --- a/style.css +++ b/style.css @@ -2,6 +2,9 @@ --main-background: white; --main-color: black; --sidebar-background: #e3e3e3; + --expander-background: #b5b5b5; + --expander-background-hover: #a6a6a6; + --expander-border: #6c6c6c; --green: green; --gray: #4a4a4a; @@ -12,6 +15,8 @@ --main-background: #212529; --main-color: #f8f9fa; --sidebar-background: #131618; + --expander-background: #424446; + --expander-background-hover: #2a2d2f; --green: #53b266; --red: #fb615b; @@ -32,7 +37,7 @@ body { font-family: monospace; } -#buffer-list, #buffer, #connect, #member-list { +#buffer, #connect { color: var(--main-color); background: var(--main-background); width: 100%; @@ -41,13 +46,43 @@ body { overflow-y: auto; } -#buffer-list { +#buffer-list, #member-list { + color: var(--main-color); + background: var(--main-background); + width: 100%; + height: 100%; + background-color: var(--sidebar-background); grid-column: 1; grid-row: 1 / 4; display: flex; - flex-direction: column; + flex-direction: row; +} + +.expander { + visibility: collapse; + cursor: pointer; + padding: 0; + margin: 0; + background: var(--expander-background); + transition: background 0.25s linear; + border: none; + width: 10px; +} + +.expander:hover { + background: var(--expander-background-hover); +} + +.expander span { + display: block; + width: 100%; + height: 2px; + margin-bottom: 2px; + border-style: solid; + border-width: 1px 0; + border-color: var(--expander-border); } #buffer-list ul { @@ -55,6 +90,8 @@ body { margin: 0; padding: 0; flex: 1 0 auto; + overflow-x: hidden; + overflow-y: auto; } #buffer-list li a { display: inline-block; @@ -108,21 +145,46 @@ body { grid-column: 2; } -#member-list-header { - grid-row: 1; +#member-list { + grid-row: 1 / 4; grid-column: 3; + width: 100%; + height: 100%; + display: flex; + flex-direction: row; +} + +#member-list > section { + display: flex; + flex-direction: column; +} + +#member-list-header { border-left: 1px solid var(--sidebar-background); } -#member-list { - grid-row: 2; - grid-column: 3; - border-left: 1px solid var(--sidebar-background); + +@media(max-width: 640px) { + #buffer-list ul { + width: 0px; + } + + #buffer-list.expand { + z-index: 999; + grid-column: 1 / 4; + } + + #buffer-list.expand ul { + width: auto; + } } #member-list ul { list-style-type: none; margin: 0; padding: 0; + flex-grow: 1; + overflow-x: hidden; + overflow-y: auto; } #member-list li a { display: inline-block; @@ -135,7 +197,7 @@ body { color: var(--main-color); background: var(--main-background); grid-row: 3; - grid-column: 2 / 4; + grid-column: 2 / 3; border-top: 1px solid var(--sidebar-background); } #composer input { @@ -471,3 +533,31 @@ kbd { box-shadow: inset 0 -1px 0 var(--outline-color); } } + +@media(max-width: 640px) { + .expander { + visibility: visible; + } + + #buffer-list ul, #member-list > section { + width: 0px; + } + + #buffer-list.expand, #member-list.expand { + z-index: 999; + grid-column-start: 1; + grid-column-end: 4; + } + + #buffer-list.expand ul { + width: auto; + } + + #member-list.expand > section { + width: 100%; + } + + #member-list-header { + border-left: none; + } +}