Add note context menu

This commit is contained in:
2023-01-20 22:59:26 +00:00
parent 34762d7039
commit e4b317f634
6 changed files with 146 additions and 60 deletions

View File

@ -1,43 +1,55 @@
.note.thread {
border-bottom: none;
border-bottom: none;
}
.note > .header .reply {
font-size: var(--font-size-tiny);
color: var(--font-secondary-color);
.note>.header .reply {
font-size: var(--font-size-tiny);
color: var(--font-secondary-color);
}
.note > .header > .info {
font-size: var(--font-size);
white-space: nowrap;
color: var(--font-secondary-color);
.note>.header>.info {
font-size: var(--font-size);
white-space: nowrap;
color: var(--font-secondary-color);
}
.note > .body {
margin-top: 12px;
padding-left: 56px;
text-overflow: ellipsis;
white-space: pre-wrap;
word-break: normal;
overflow-x: hidden;
overflow-y: visible;
.note>.body {
margin-top: 12px;
padding-left: 56px;
text-overflow: ellipsis;
white-space: pre-wrap;
word-break: normal;
overflow-x: hidden;
overflow-y: visible;
}
.note > .footer {
padding-left: 46px;
.note>.footer {
padding-left: 46px;
}
.note > .header img:hover, .note > .header .name > .reply:hover, .note .body:hover {
cursor: pointer;
.note>.footer .ctx-menu {
background-color: var(--note-bg);
color: var(--font-secondary-color);
border: 1px solid var(--font-secondary-color);
border-radius: 16px;
}
.note > .note-creator {
.note>.header img:hover, .note>.header .name>.reply:hover, .note .body:hover {
cursor: pointer;
}
.note>.note-creator {
margin-top: 12px;
}
@media (min-width: 720px) {
.note > .footer { margin-top: 24px; }
.note > .note-creator { margin-top: 24px; }
.note>.footer {
margin-top: 24px;
}
.note>.note-creator {
margin-top: 24px;
}
}
@ -55,8 +67,8 @@
}
.indented {
border-left: 3px solid var(--gray-tertiary);
padding-left: 2px;
border-left: 3px solid var(--gray-tertiary);
padding-left: 2px;
}
.note:last-child {
@ -69,16 +81,16 @@
margin-bottom: 24px;
}
.indented > .indented .note:last-child {
.indented>.indented .note:last-child {
border-bottom-right-radius: 0px;
margin-bottom: 0;
}
.indented .active {
background-color: var(--gray-tertiary);
margin-left: -5px;
border-left: 3px solid var(--highlight);
border-radius: 0;
background-color: var(--gray-tertiary);
margin-left: -5px;
border-left: 3px solid var(--highlight);
border-radius: 0;
}
.reaction-pill {
@ -95,7 +107,7 @@
}
.reaction-pill.reacted {
color: var(--highlight);
color: var(--highlight);
}
.reaction-pill:hover {
@ -107,33 +119,36 @@
margin-right: auto;
}
.note.active > .header .reply {
.note.active>.header .reply {
color: var(--font-tertiary-color);
}
.note.active > .header > .info {
.note.active>.header>.info {
color: var(--font-tertiary-color);
}
.note.active > .footer > .reaction-pill {
.note.active>.footer>.reaction-pill {
color: var(--font-tertiary-color);
}
.note.active > .footer > .reaction-pill.reacted {
.note.active>.footer>.reaction-pill.reacted {
color: var(--highlight);
}
@media (prefers-color-scheme: light) {
.indented .active {
background-color: var(--gray-secondary);
background-color: var(--gray-secondary);
}
.note.active > .header .reply {
.note.active>.header .reply {
color: var(--font-secondary-color);
}
.note.active > .header > .info {
.note.active>.header>.info {
color: var(--font-secondary-color);
}
.note.active > .footer > .reaction-pill {
.note.active>.footer>.reaction-pill {
color: var(--font-secondary-color);
}
}
}

View File

@ -1,11 +1,12 @@
import { useMemo, useState } from "react";
import { useSelector } from "react-redux";
import { faHeart, faReply, faThumbsDown, faTrash, faBolt, faRepeat } from "@fortawesome/free-solid-svg-icons";
import { faHeart, faReply, faThumbsDown, faTrash, faBolt, faRepeat, faEllipsisVertical, faShareNodes } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Menu, MenuItem } from '@szhsin/react-menu';
import { formatShort } from "Number";
import useEventPublisher from "Feed/EventPublisher";
import { getReactions, normalizeReaction, Reaction } from "Util";
import { getReactions, hexToBech32, normalizeReaction, Reaction } from "Util";
import { NoteCreator } from "Element/NoteCreator";
import LNURLTip from "Element/LNURLTip";
import useProfile from "Feed/ProfileFeed";
@ -79,7 +80,7 @@ export default function NoteFooter(props: NoteFooterProps) {
if (service) {
return (
<>
<div className="reaction-pill" onClick={(e) => setTip(true)}>
<div className="reaction-pill" onClick={() => setTip(true)}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faBolt} />
</div>
@ -111,7 +112,7 @@ export default function NoteFooter(props: NoteFooterProps) {
}
return (
<>
<div className={`reaction-pill ${hasReacted('+') ? 'reacted' : ''} `} onClick={(e) => react("+")}>
<div className={`reaction-pill ${hasReacted('+') ? 'reacted' : ''} `} onClick={() => react("+")}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faHeart} />
</div>
@ -119,19 +120,57 @@ export default function NoteFooter(props: NoteFooterProps) {
{formatShort(groupReactions[Reaction.Positive])}
</div>
</div>
<div className={`reaction-pill ${hasReacted('-') ? 'reacted' : ''}`} onClick={(e) => react("-")}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faThumbsDown} />
</div>
<div className="reaction-pill-number">
{formatShort(groupReactions[Reaction.Negative])}
</div>
</div>
{repostIcon()}
</>
)
}
async function share() {
const url = `${window.location.protocol}//${window.location.host}/e/${hexToBech32("npub", ev.Id)}`;
if ("share" in window.navigator) {
await window.navigator.share({
title: "Snort",
url: url
});
} else {
await navigator.clipboard.writeText(url);
}
}
function menuItems() {
return (
<>
<MenuItem onClick={() => react("-")}>
<div className={`reaction-pill ${hasReacted('-') ? 'reacted' : ''}`}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faThumbsDown} />
</div>
<div className="reaction-pill-number">
{formatShort(groupReactions[Reaction.Negative])}
</div>
</div>
Dislike
</MenuItem>
<MenuItem onClick={() => share()}>
<div className="reaction-pill mr-auto">
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faShareNodes} />
</div>
</div>
Share
</MenuItem>
{isMine && (
<MenuItem onClick={() => deleteEvent()}>
<div className="reaction-pill trash-icon">
<FontAwesomeIcon icon={faTrash} />
</div>
Delete
</MenuItem>
)}
</>
)
}
return (
<>
<div className="footer">
@ -140,15 +179,16 @@ export default function NoteFooter(props: NoteFooterProps) {
<FontAwesomeIcon icon={faReply} />
</div>
</div>
<Menu menuButton={<div className="reaction-pill">
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faEllipsisVertical} />
</div>
</div>} menuClassName="ctx-menu">
{menuItems()}
</Menu>
{reactionIcons()}
{tipButton()}
{isMine && (
<div className="reaction-pill trash-icon">
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faTrash} onClick={(e) => deleteEvent()} />
</div>
</div>
)}
</div>
<NoteCreator
autoFocus={true}