feat: relays cleanup

This commit is contained in:
Kieran 2023-11-07 13:55:09 +00:00
parent fcd2c8a3a0
commit e627cddd24
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
6 changed files with 69 additions and 135 deletions

View File

@ -141,7 +141,6 @@
.trash-icon { .trash-icon {
color: var(--error); color: var(--error);
margin-right: auto;
} }
.note-expand .body { .note-expand .body {

View File

@ -1,8 +1,6 @@
.relay { .relay {
margin-top: 10px;
background-color: var(--gray-secondary); background-color: var(--gray-secondary);
border-radius: 5px; border-radius: 5px;
text-align: start;
display: grid; display: grid;
grid-template-columns: min-content auto; grid-template-columns: min-content auto;
overflow: hidden; overflow: hidden;
@ -12,33 +10,3 @@
.relay > div { .relay > div {
padding: 5px; padding: 5px;
} }
.relay-extra {
padding: 5px;
margin: 0 5px;
background-color: var(--gray-tertiary);
border-radius: 0 0 5px 5px;
white-space: nowrap;
font-size: var(--font-size-small);
}
.icon-btn {
padding: 2px 10px;
border-radius: 10px;
background-color: var(--gray);
user-select: none;
color: var(--font-color);
display: inline-block;
}
.icon-btn:hover {
cursor: pointer;
}
.checkmark {
margin-left: 0.5em;
padding: 2px 10px;
background-color: var(--gray);
border-radius: 10px;
display: inline-block;
}

View File

@ -1,18 +1,17 @@
import "./Relay.css"; import "./Relay.css";
import { useContext, useMemo } from "react"; import { useContext, useMemo } from "react";
import { FormattedMessage } from "react-intl";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { RelaySettings } from "@snort/system"; import { RelaySettings } from "@snort/system";
import { unixNowMs } from "@snort/shared"; import { unixNowMs } from "@snort/shared";
import classNames from "classnames";
import useRelayState from "Feed/RelayState"; import useRelayState from "Feed/RelayState";
import { SnortContext } from "@snort/system-react"; import { SnortContext } from "@snort/system-react";
import { getRelayName, unwrap } from "SnortUtils"; import { getRelayName, unwrap } from "SnortUtils";
import useLogin from "Hooks/useLogin"; import useLogin from "Hooks/useLogin";
import { setRelays } from "Login"; import { removeRelay, setRelays } from "Login";
import Icon from "Icons/Icon"; import { RelayFavicon } from "./RelaysMetadata";
import { AsyncIcon } from "Element/AsyncIcon";
import messages from "../messages";
export interface RelayProps { export interface RelayProps {
addr: string; addr: string;
@ -42,48 +41,52 @@ export default function Relay(props: RelayProps) {
return ( return (
<> <>
<div className={`relay w-max`}> <div className="relay">
<div className={`flex ${state?.connected ? "bg-success" : "bg-error"}`}> <div className={classNames("flex items-center", state?.connected ? "bg-success" : "bg-error")}>
<Icon name="wifi" /> <RelayFavicon url={props.addr} />
</div> </div>
<div className="grow flex-col"> <div className="flex flex-col g8">
<div className="flex mb10"> <div>
<b className="f-2">{name}</b> <b>{name}</b>
<div className="f-1"> </div>
<FormattedMessage {...messages.Write} /> {!state?.ephemeral && (
<span <div className="flex g8">
className="checkmark" <AsyncIcon
iconName="write"
iconSize={16}
className={classNames("button-icon-sm transparent", { active: relaySettings.write })}
onClick={() => onClick={() =>
configure({ configure({
write: !relaySettings.write, write: !relaySettings.write,
read: relaySettings.read, read: relaySettings.read,
}) })
}> }
<Icon name={relaySettings.write ? "check" : "close"} size={12} /> />
</span> <AsyncIcon
</div> iconName="read"
<div className="f-1"> iconSize={16}
<FormattedMessage {...messages.Read} /> className={classNames("button-icon-sm transparent", { active: relaySettings.read })}
<span
className="checkmark"
onClick={() => onClick={() =>
configure({ configure({
write: relaySettings.write, write: relaySettings.write,
read: !relaySettings.read, read: !relaySettings.read,
}) })
}> }
<Icon name={relaySettings.read ? "check" : "close"} size={12} /> />
</span> <AsyncIcon
iconName="trash"
iconSize={16}
className="button-icon-sm transparent trash-icon"
onClick={() => removeRelay(login, props.addr)}
/>
<AsyncIcon
iconName="gear"
iconSize={16}
className="button-icon-sm transparent"
onClick={() => navigate(state?.id ?? "")}
/>
</div> </div>
</div> )}
<div className="flex">
<div className="grow"></div>
<div>
<span className="icon-btn" onClick={() => navigate(state?.id ?? "")}>
<Icon name="gear" size={12} />
</span>
</div>
</div>
</div> </div>
</div> </div>
</> </>

View File

@ -1,45 +1,9 @@
.favicon { .favicon {
width: 21px; width: 21px;
height: 21px; height: 21px;
border-radius: 100%; max-width: unset;
margin-right: 12px;
} }
.relay-card { .relay-active {
display: flex;
flex-direction: row;
align-items: center;
}
.relay-settings {
margin-left: auto;
display: flex;
align-items: center;
}
.relay-settings svg:not(:last-child) {
margin-right: 12px;
}
.relay-settings svg.enabled {
color: var(--highlight); color: var(--highlight);
} }
.relay-settings svg.disabled {
opacity: 0.3;
}
@media (max-width: 520px) {
.relay-settings svg {
width: 16px;
height: 16px;
}
}
.relay-url {
font-size: 14px;
}
@media (min-width: 520px) {
.relay-url {
font-size: 16px;
}
}

View File

@ -5,14 +5,19 @@ import { useState } from "react";
import { FullRelaySettings } from "@snort/system"; import { FullRelaySettings } from "@snort/system";
import Icon from "Icons/Icon"; import Icon from "Icons/Icon";
const RelayFavicon = ({ url }: { url: string }) => { export const RelayFavicon = ({ url }: { url: string }) => {
const cleanUrl = url const cleanUrl = url
.replace(/^wss:\/\//, "https://") .replace(/^wss:\/\//, "https://")
.replace(/^ws:\/\//, "http://") .replace(/^ws:\/\//, "http://")
.replace(/\/$/, ""); .replace(/\/$/, "");
const [faviconUrl, setFaviconUrl] = useState(`${cleanUrl}/favicon.ico`); const [faviconUrl, setFaviconUrl] = useState(`${cleanUrl}/favicon.ico`);
return ( return (
<img className="favicon" src={faviconUrl} onError={() => setFaviconUrl(Nostrich)} alt={`favicon for ${url}`} /> <img
className="circle favicon"
src={faviconUrl}
onError={() => setFaviconUrl(Nostrich)}
alt={`favicon for ${url}`}
/>
); );
}; };
@ -25,12 +30,12 @@ const RelaysMetadata = ({ relays }: RelaysMetadataProps) => {
<> <>
{relays?.map(({ url, settings }) => { {relays?.map(({ url, settings }) => {
return ( return (
<div key={url} className="card relay-card"> <div key={url} className="card flex g8">
<RelayFavicon url={url} /> <RelayFavicon url={url} />
<code className="relay-url f-ellipsis">{url}</code> <code className="grow f-ellipsis">{url}</code>
<div className="relay-settings"> <div className="flex g8">
<Icon name="read" className={settings.read ? "enabled" : "disabled"} /> <Icon name="read" className={settings.read ? "relay-active" : "disabled"} />
<Icon name="write" className={settings.write ? "enabled" : "disabled"} /> <Icon name="write" className={settings.write ? "relay-active" : "disabled"} />
</div> </div>
</div> </div>
); );

View File

@ -45,23 +45,21 @@ const RelaySettingsPage = () => {
function addRelay() { function addRelay() {
return ( return (
<> <div className="flex flex-col g8">
<h4> <h4>
<FormattedMessage {...messages.AddRelays} /> <FormattedMessage {...messages.AddRelays} />
</h4> </h4>
<div className="flex mb10"> <input
<input type="text"
type="text" className="grow"
className="grow" placeholder="wss://my-relay.com"
placeholder="wss://my-relay.com" value={newRelay}
value={newRelay} onChange={handleNewRelayChange}
onChange={handleNewRelayChange} />
/> <button className="secondary" onClick={() => addNewRelay()}>
</div>
<button className="secondary mb10" onClick={() => addNewRelay()}>
<FormattedMessage {...messages.Add} /> <FormattedMessage {...messages.Add} />
</button> </button>
</> </div>
); );
} }
@ -77,31 +75,28 @@ const RelaySettingsPage = () => {
} }
return ( return (
<> <div className="flex flex-col g8">
<h3> <h3>
<FormattedMessage {...messages.Relays} /> <FormattedMessage {...messages.Relays} />
</h3> </h3>
<div className="flex flex-col mb10"> <div className="flex flex-col g8">
{Object.keys(relays.item || {}).map(a => ( {Object.keys(relays.item || {}).map(a => (
<Relay addr={a} key={a} /> <Relay addr={a} key={a} />
))} ))}
</div> </div>
<div className="flex mt10"> <AsyncButton type="button" onClick={() => saveRelays(system, publisher, relays.item)} disabled={login.readonly}>
<div className="grow"></div> <FormattedMessage {...messages.Save} />
<AsyncButton type="button" onClick={() => saveRelays(system, publisher, relays.item)} disabled={login.readonly}> </AsyncButton>
<FormattedMessage {...messages.Save} />
</AsyncButton>
</div>
{addRelay()} {addRelay()}
<h3> <h3>
<FormattedMessage defaultMessage="Other Connections" /> <FormattedMessage defaultMessage="Other Connections" />
</h3> </h3>
<div className="flex flex-col mb10"> <div className="flex flex-col g8">
{otherConnections.map(a => ( {otherConnections.map(a => (
<Relay addr={a.address} key={a.id} /> <Relay addr={a.address} key={a.id} />
))} ))}
</div> </div>
</> </div>
); );
}; };