Add a lot of styling
This commit is contained in:
parent
3f1e6cf657
commit
4872eee4ed
6 changed files with 180 additions and 37 deletions
|
@ -3,6 +3,8 @@
|
|||
|
||||
<head>
|
||||
<title>Ripcord log viewer</title>
|
||||
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed:300,400&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="style/layout.scss" />
|
||||
</head>
|
||||
|
||||
|
|
|
@ -11,6 +11,13 @@ function channelsFirst(a: GQLChannel, b: GQLChannel): number {
|
|||
return a.name > b.name ? 1 : -1;
|
||||
}
|
||||
|
||||
function isActive(currentChatData, ws, ch): boolean {
|
||||
return (
|
||||
currentChatData?.currentChat?.workspace == ws &&
|
||||
currentChatData?.currentChat?.channel == ch
|
||||
);
|
||||
}
|
||||
|
||||
export default function ChannelList() {
|
||||
const { loading, error, data } = useQuery(gql`
|
||||
{
|
||||
|
@ -31,6 +38,15 @@ export default function ChannelList() {
|
|||
}
|
||||
`);
|
||||
|
||||
const { loading: currentChatLoading, data: currentChatData } = useQuery(gql`
|
||||
{
|
||||
currentChat {
|
||||
workspace
|
||||
channel
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
if (loading) {
|
||||
return <div>Loading</div>;
|
||||
}
|
||||
|
@ -51,6 +67,9 @@ export default function ChannelList() {
|
|||
{ws.channels.sort(channelsFirst).map(ch => (
|
||||
<li
|
||||
key={ch.name}
|
||||
className={
|
||||
isActive(currentChatData, ws.name, ch.name) ? "active" : ""
|
||||
}
|
||||
onClick={a =>
|
||||
gotoChat({
|
||||
variables: { workspace: ws.name, channel: ch.name }
|
||||
|
|
|
@ -1,8 +1,40 @@
|
|||
import React from "react";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useQuery } from "@apollo/react-hooks";
|
||||
import { gql } from "apollo-boost";
|
||||
import { GQLMessage } from "./gql-types";
|
||||
|
||||
function perDay(messages: GQLMessage[]) {
|
||||
const days = messages.reduce((acc, msg) => {
|
||||
const [day] = msg.time.split("T");
|
||||
if (!(day in acc)) {
|
||||
acc[day] = [];
|
||||
}
|
||||
acc[day].push(msg);
|
||||
return acc;
|
||||
}, {});
|
||||
return Object.entries(days).sort(([a], [b]) => {
|
||||
if (a > b) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
||||
function formatTime(time: string): string {
|
||||
const t = new Date(time);
|
||||
return [t.getHours(), t.getMinutes(), t.getSeconds()]
|
||||
.map(x => `0${x}`.slice(-2))
|
||||
.join(":");
|
||||
}
|
||||
|
||||
function colorname(name: string): string {
|
||||
const n = name
|
||||
.split("")
|
||||
.map(x => x.charCodeAt(0))
|
||||
.reduce((a, b) => a + b, 0);
|
||||
return `hsl(${n % 360}, 60%, 50%)`;
|
||||
}
|
||||
|
||||
export default function Chatroom() {
|
||||
const {
|
||||
loading: localLoading,
|
||||
|
@ -47,6 +79,11 @@ export default function Chatroom() {
|
|||
}
|
||||
);
|
||||
|
||||
const lastMessage = useRef(null);
|
||||
useEffect(() => {
|
||||
lastMessage.current?.scrollIntoView();
|
||||
});
|
||||
|
||||
if (localLoading || remoteLoading) {
|
||||
return <div>Loading</div>;
|
||||
}
|
||||
|
@ -64,17 +101,34 @@ export default function Chatroom() {
|
|||
return (
|
||||
<div>
|
||||
<ul className="chatlog">
|
||||
{remoteData.messages.messages.map((msg: GQLMessage) => (
|
||||
<li key={msg.messageId}>
|
||||
<article className="message">
|
||||
<header>
|
||||
{msg.userRealname} ({msg.username}) ({msg.messageId})
|
||||
</header>
|
||||
<p>{msg.content}</p>
|
||||
</article>
|
||||
{perDay(remoteData.messages.messages).map(([day, messages]) => (
|
||||
<li>
|
||||
<div className="day">{day}</div>
|
||||
<ul>
|
||||
{messages.map((msg: GQLMessage) => (
|
||||
<li key={msg.messageId}>
|
||||
<article className="message">
|
||||
<header>
|
||||
<div className="time" title={msg.time}>
|
||||
{formatTime(msg.time)}
|
||||
</div>
|
||||
<div
|
||||
className="realname"
|
||||
style={{ color: colorname(msg.username) }}
|
||||
>
|
||||
{msg.userRealname}
|
||||
</div>
|
||||
<div className="username">{msg.username}</div>
|
||||
</header>
|
||||
<p>{msg.content}</p>
|
||||
</article>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div ref={lastMessage}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ export interface GQLMessageList {
|
|||
}
|
||||
|
||||
export interface GQLMessage {
|
||||
time: Date;
|
||||
time: string;
|
||||
content: string;
|
||||
username: string;
|
||||
userRealname: string;
|
||||
|
|
|
@ -3,10 +3,103 @@
|
|||
flex: 1;
|
||||
}
|
||||
|
||||
|
||||
body,
|
||||
.main {
|
||||
@include full;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
font-family: "Inter var", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
}
|
||||
|
||||
@import "./sidebar.scss";
|
||||
.chatroom {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
|
||||
.day {
|
||||
text-align: center;
|
||||
padding: 10pt;
|
||||
top: 0;
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
.message {
|
||||
header {
|
||||
display: flex;
|
||||
|
||||
div {
|
||||
padding: 0 5pt;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-family: "Roboto Condensed";
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.realname {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.username {
|
||||
color: grey;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0 15pt;
|
||||
margin: 5pt 0 15pt 0;
|
||||
font-size: 11pt;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.channelList {
|
||||
flex: 0 200px;
|
||||
overflow-y: scroll;
|
||||
|
||||
.workspace {
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10pt;
|
||||
|
||||
img {
|
||||
max-height: 2em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.chats {
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 4pt 5pt;
|
||||
font-size: 10pt;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: grey;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: blue;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
.channelList {
|
||||
.workspace {
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
max-height: 2em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.chats {
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 2pt 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue