Change how chat actions look

remotes/1693176582716663532/tmp_refs/heads/watchparty
Outrun Colors 2022-09-25 14:23:10 -05:00
parent c51c7c91b6
commit 96bf16484c
No known key found for this signature in database
GPG Key ID: 0426976DCEFE6073
6 changed files with 145 additions and 49 deletions

View File

@ -37,6 +37,7 @@ body {
.App-heading small {
opacity: 0.2;
font-size: 10px;
}
.App-side {
@ -122,4 +123,9 @@ lite-youtube {
.btn-secondary {
border: none !important;
}
.btn-secondary:focus {
border: none !important;
box-shadow: none !important;
}

View File

@ -10,8 +10,20 @@
.ChatMessage {
position: relative;
animation: fading-in 0.3s ease-in-out forwards;
padding: 1rem;
padding-right: 3rem;
padding-right: 1.5rem;
min-height: 28px;
}
.ChatMessage p {
margin: 0;
}
.ChatMessage__showingUser:not(:first-child) {
margin-top: 2rem;
}
.ChatMessage:not(.ChatMessage__showingUser) {
padding-bottom: 0;
}
.ChatMessage .btn {
@ -25,6 +37,8 @@
.ChatMessage-timestamp {
margin-left: 0.5rem;
opacity: 0.5;
font-size: 10px;
}
.ChatMessage-bottom {
@ -41,20 +55,51 @@
}
.ChatMessage-button {
background: transparent !important;
margin: 0 0.5rem;
}
.ChatMessage-button__confirmed i {
.ChatMessage-button i {
margin-right: 0.5rem;
}
.ChatMessage-button__confirmed {
color: red !important;
}
.ChatMessage-delete {
.ChatMessage-actions-button {
position: absolute;
top: 4px;
right: 4px;
top: 0;
right: 0;
cursor: pointer;
z-index: 5;
background: none !important;
border: none !important;
box-shadow: none !important;
}
.ChatMessage-actions {
z-index: 1;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(20, 20, 20, 0.85);
display: flex;
align-items: center;
justify-content: flex-end;
padding: 1rem;
padding-right: 3rem;
animation: fading-in 0.3s ease-in-out forwards;
}
.ChatMessage-actions button {
font-size: 10px;
background: none !important;
}
/* List */
.ChatMessageList {
flex: 1;
padding-bottom: 2rem;
}

View File

@ -1,9 +1,4 @@
import React, {
useCallback,
useEffect,
useMemo,
useState,
} from "react";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import cx from "classnames";
import key from "weak-key";
import humanizeDuration from "humanize-duration";
@ -37,20 +32,16 @@ export function ChatMessage({
time,
quotes,
} = message;
const {
username: loggedInUsername,
admin,
censored,
themeColor,
} = useRootContext();
const { admin, censored } = useRootContext();
const { messageLookup, deleteMessage, quoteMessage } = useChat();
const quotedMessage = messageLookup[quotes];
const content = censored ? text_censored : text_html;
const hasMention = content.includes(loggedInUsername);
const mentionStyle = hasMention
? { backgroundColor: `#${themeColor}55` }
: {};
const [showingActions, setShowingActions] = useState(false);
const [confirmedDelete, setConfirmedDelete] = useState(false);
const timestamp = useMemo(
() => formatTimeAgo(time),
[time, timestampUpdates]
);
const handleDeleteMessage = useCallback(() => {
if (confirmedDelete) {
deleteMessage(text);
@ -58,13 +49,63 @@ export function ChatMessage({
setConfirmedDelete(true);
}
}, [text, confirmedDelete]);
const timestamp = useMemo(
() => formatTimeAgo(time),
[time, timestampUpdates]
const toggleMessageActions = useCallback(
() => setShowingActions((prev) => !prev),
[]
);
const handleQuoteMessage = useCallback(() => {
quoteMessage(message);
setShowingActions(false);
}, [message]);
useEffect(() => {
if (!showingActions) {
setConfirmedDelete(false);
}
}, [showingActions]);
return (
<div className="ChatMessage" style={mentionStyle} id={id}>
<div
className={cx("ChatMessage", {
ChatMessage__showingUser: showUser,
})}
id={id}
>
{!showingActions && (
<button
className="btn btn-secondary ChatMessage-actions-button"
onClick={toggleMessageActions}
>
...
</button>
)}
{showingActions && (
<div className="ChatMessage-actions">
<button
className="btn btn-secondary ChatMessage-button"
onClick={handleQuoteMessage}
>
<i className="fas fa-reply" /> Reply
</button>
{admin && (
<button
className={cx("btn btn-secondary ChatMessage-button", {
"ChatMessage-button__confirmed": confirmedDelete,
})}
onClick={handleDeleteMessage}
>
<i className="fas fa-trash-alt" />{" "}
{confirmedDelete ? "Are you sure?" : "Delete"}
</button>
)}
<button
className="btn btn-secondary ChatMessage-button"
onClick={toggleMessageActions}
>
<i>X</i> Close
</button>
</div>
)}
{showUser && (
<div className="ChatMessage-top">
<Username
@ -86,23 +127,7 @@ export function ChatMessage({
__html: content,
}}
/>
<button
className="ChatMessage-button quote btn"
onClick={() => quoteMessage(message)}
>
<i className="fas fa-reply"></i>
</button>
</div>
{admin && (
<button
className={cx("ChatMessage-button ChatMessage-delete btn", {
"ChatMessage-button__confirmed": confirmedDelete,
})}
onClick={handleDeleteMessage}
>
<i className="fas fa-trash-alt"></i>
</button>
)}
</div>
</div>
);
@ -138,12 +163,28 @@ export function ChatMessageList() {
}
function formatTimeAgo(time: number) {
const now = new Date().getTime();
const humanized = `${humanizeDuration(time * 1000 - now, {
const shortEnglishHumanizer = humanizeDuration.humanizer({
language: "shortEn",
languages: {
shortEn: {
y: () => "y",
mo: () => "mo",
w: () => "w",
d: () => "d",
h: () => "h",
m: () => "m",
s: () => "s",
ms: () => "ms",
},
},
round: true,
units: ["h", "m", "s"],
largest: 2,
})} ago`;
spacer: "",
delimiter: ", ",
});
const now = new Date().getTime();
const humanized = `${shortEnglishHumanizer(time * 1000 - now)} ago`;
return humanized === "0 seconds ago" ? "just now" : humanized;
return humanized === "0s ago" ? "just now" : humanized;
}

View File

@ -0,0 +1,3 @@
.QuotedMessageLink {
font-size: 10px;
}

View File

@ -1,5 +1,6 @@
import React, { useCallback, useMemo } from "react";
import { useRootContext } from "../../hooks";
import "./QuotedMessageLink.css";
const SCROLL_TO_QUOTED_OVERFLOW = 250;
const QUOTED_MESSAGE_CONTEXTUAL_HIGHLIGHTING_DURATION = 2500;
@ -40,7 +41,7 @@ export function QuotedMessageLink({ message }: { message: IChatMessage }) {
}, [message, censored]);
return (
<a href="#" onClick={handleLinkClick}>
<a className="QuotedMessageLink" href="#" onClick={handleLinkClick}>
Replying to @{message.username}:{" "}
<em>"{replyText}"</em>
</a>

View File

@ -47,7 +47,7 @@ export function UserInput() {
);
const handleKeyUp = useCallback(
(event: KeyboardEvent<HTMLTextAreaElement>) => {
if (event.key === "Enter") {
if (event.key === "Enter" && !event.shiftKey) {
handleSendMessage();
}
},