User preferences #104

Merged
v0l merged 2 commits from preferences into main 2023-01-20 20:10:17 +00:00
17 changed files with 524 additions and 507 deletions

View File

@ -13,148 +13,150 @@ import { default as NEvent } from "Nostr/Event";
import { RootState } from "State/Store";
import { HexKey, TaggedRawEvent } from "Nostr";
import EventKind from "Nostr/EventKind";
import { UserPreferences } from "State/Login";
export interface NoteFooterProps {
related: TaggedRawEvent[],
ev: NEvent
related: TaggedRawEvent[],
ev: NEvent
}
export default function NoteFooter(props: NoteFooterProps) {
const { related, ev } = props;
const { related, ev } = props;
const login = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
const author = useProfile(ev.RootPubKey)?.get(ev.RootPubKey);
const publisher = useEventPublisher();
const [reply, setReply] = useState(false);
const [tip, setTip] = useState(false);
const isMine = ev.RootPubKey === login;
const reactions = useMemo(() => getReactions(related, ev.Id, EventKind.Reaction), [related]);
const reposts = useMemo(() => getReactions(related, ev.Id, EventKind.Repost), [related]);
const groupReactions = useMemo(() => {
return reactions?.reduce((acc, { content }) => {
let r = normalizeReaction(content);
const amount = acc[r] || 0
return { ...acc, [r]: amount + 1 }
}, {
[Reaction.Positive]: 0,
[Reaction.Negative]: 0
});
}, [reactions]);
const login = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
const prefs = useSelector<RootState, UserPreferences>(s => s.login.preferences);
const author = useProfile(ev.RootPubKey)?.get(ev.RootPubKey);
const publisher = useEventPublisher();
const [reply, setReply] = useState(false);
const [tip, setTip] = useState(false);
const isMine = ev.RootPubKey === login;
const reactions = useMemo(() => getReactions(related, ev.Id, EventKind.Reaction), [related]);
const reposts = useMemo(() => getReactions(related, ev.Id, EventKind.Repost), [related]);
const groupReactions = useMemo(() => {
return reactions?.reduce((acc, { content }) => {
let r = normalizeReaction(content);
const amount = acc[r] || 0
return { ...acc, [r]: amount + 1 }
}, {
[Reaction.Positive]: 0,
[Reaction.Negative]: 0
});
}, [reactions]);
function hasReacted(emoji: string) {
return reactions?.some(({ pubkey, content }) => normalizeReaction(content) === emoji && pubkey === login)
function hasReacted(emoji: string) {
return reactions?.some(({ pubkey, content }) => normalizeReaction(content) === emoji && pubkey === login)
}
function hasReposted() {
return reposts.some(a => a.pubkey === login);
}
async function react(content: string) {
if (!hasReacted(content)) {
let evLike = await publisher.react(ev, content);
publisher.broadcast(evLike);
}
}
function hasReposted() {
return reposts.some(a => a.pubkey === login);
async function deleteEvent() {
if (window.confirm(`Are you sure you want to delete ${ev.Id.substring(0, 8)}?`)) {
let evDelete = await publisher.delete(ev.Id);
publisher.broadcast(evDelete);
}
}
async function react(content: string) {
if (!hasReacted(content)) {
let evLike = await publisher.react(ev, content);
publisher.broadcast(evLike);
async function repost() {
if (!hasReposted()) {
if (!prefs.confirmReposts || window.confirm(`Are you sure you want to repost: ${ev.Id}`)) {
let evRepost = await publisher.repost(ev);
publisher.broadcast(evRepost);
}
}
}
async function deleteEvent() {
if (window.confirm(`Are you sure you want to delete ${ev.Id.substring(0, 8)}?`)) {
let evDelete = await publisher.delete(ev.Id);
publisher.broadcast(evDelete);
}
}
async function repost() {
if (!hasReposted()) {
let evRepost = await publisher.repost(ev);
publisher.broadcast(evRepost);
}
}
function tipButton() {
let service = author?.lud16 || author?.lud06;
if (service) {
return (
<>
<div className="reaction-pill" onClick={(e) => setTip(true)}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faBolt} />
</div>
</div>
</>
)
}
return null;
}
function reactionIcon(content: string, reacted: boolean) {
switch (content) {
case Reaction.Positive: {
return <FontAwesomeIcon icon={faHeart} />;
}
case Reaction.Negative: {
return <FontAwesomeIcon icon={faThumbsDown} />;
}
}
return content;
}
function repostIcon() {
function tipButton() {
let service = author?.lud16 || author?.lud06;
if (service) {
return (
<div className={`reaction-pill ${hasReposted() ? 'reacted' : ''}`} onClick={() => repost()}>
<>
<div className="reaction-pill" onClick={(e) => setTip(true)}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faRepeat} />
<FontAwesomeIcon icon={faBolt} />
</div>
{reposts.length > 0 && (
<div className="reaction-pill-number">
{formatShort(reposts.length)}
</div>
)}
</div>
</>
)
}
return null;
}
function repostIcon() {
return (
<>
<div className="footer">
<div className={`reaction-pill ${reply ? 'reacted' : ''}`} onClick={(e) => setReply(s => !s)}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faReply} />
</div>
</div>
<div className={`reaction-pill ${hasReacted('+') ? 'reacted' : ''} `} onClick={(e) => react("+")}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faHeart} />
</div>
<div className="reaction-pill-number">
{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()}
{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}
replyTo={ev}
onSend={() => setReply(false)}
show={reply}
/>
<LNURLTip svc={author?.lud16 || author?.lud06} onClose={() => setTip(false)} show={tip} />
</>
<div className={`reaction-pill ${hasReposted() ? 'reacted' : ''}`} onClick={() => repost()}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faRepeat} />
</div>
{reposts.length > 0 && (
<div className="reaction-pill-number">
{formatShort(reposts.length)}
</div>
)}
</div>
)
}
function reactionIcons() {
if (!prefs.enableReactions) {
return null;
}
return (
<>
<div className={`reaction-pill ${hasReacted('+') ? 'reacted' : ''} `} onClick={(e) => react("+")}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faHeart} />
</div>
<div className="reaction-pill-number">
{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()}
</>
)
}
return (
<>
<div className="footer">
<div className={`reaction-pill ${reply ? 'reacted' : ''}`} onClick={(e) => setReply(s => !s)}>
<div className="reaction-pill-icon">
<FontAwesomeIcon icon={faReply} />
</div>
</div>
{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}
replyTo={ev}
onSend={() => setReply(false)}
show={reply}
/>
<LNURLTip svc={author?.lud16 || author?.lud06} onClose={() => setTip(false)} show={tip} />
</>
)
}

View File

@ -13,9 +13,15 @@ import Tag from "Nostr/Tag";
import { MetadataCache } from "Db/User";
import Mention from "Element/Mention";
import TidalEmbed from "Element/TidalEmbed";
import { useSelector } from 'react-redux';
import { RootState } from 'State/Store';
import { UserPreferences } from 'State/Login';
function transformHttpLink(a: string) {
function transformHttpLink(a: string, pref: UserPreferences) {
try {
if (!pref.autoLoadMedia) {
return <a href={a} onClick={(e) => e.stopPropagation()} target="_blank" rel="noreferrer" className="ext">{a}</a>
}
const url = new URL(a);
const youtubeId = YoutubeUrlRegex.test(a) && RegExp.$1;
const tweetId = TweetUrlRegex.test(a) && RegExp.$2;
@ -73,12 +79,12 @@ function transformHttpLink(a: string) {
return <a href={a} onClick={(e) => e.stopPropagation()} target="_blank" rel="noreferrer" className="ext">{a}</a>
}
function extractLinks(fragments: Fragment[]) {
function extractLinks(fragments: Fragment[], pref: UserPreferences) {
return fragments.map(f => {
if (typeof f === "string") {
return f.split(UrlRegex).map(a => {
if (a.startsWith("http")) {
return transformHttpLink(a)
return transformHttpLink(a, pref)
}
return a;
});
@ -87,14 +93,14 @@ function extractLinks(fragments: Fragment[]) {
}).flat();
}
function extractMentions(fragments: Fragment[], tags: Tag[], users: Map<string, MetadataCache>) {
return fragments.map(f => {
function extractMentions(frag: TextFragment) {
return frag.body.map(f => {
if (typeof f === "string") {
return f.split(MentionRegex).map((match) => {
let matchTag = match.match(/#\[(\d+)\]/);
if (matchTag && matchTag.length === 2) {
let idx = parseInt(matchTag[1]);
let ref = tags?.find(a => a.Index === idx);
let ref = frag.tags?.find(a => a.Index === idx);
if (ref) {
switch (ref.Key) {
case "p": {
@ -149,25 +155,25 @@ function extractHashtags(fragments: Fragment[]) {
}).flat();
}
function transformLi({ body, tags, users }: TextFragment) {
let fragments = transformText({ body, tags, users })
function transformLi(frag: TextFragment) {
let fragments = transformText(frag)
return <li>{fragments}</li>
}
function transformParagraph({ body, tags, users }: TextFragment) {
const fragments = transformText({ body, tags, users })
function transformParagraph(frag: TextFragment) {
const fragments = transformText(frag)
if (fragments.every(f => typeof f === 'string')) {
return <p>{fragments}</p>
}
return <>{fragments}</>
}
function transformText({ body, tags, users }: TextFragment) {
if (body === undefined) {
function transformText(frag: TextFragment) {
if (frag.body === undefined) {
debugger;
}
let fragments = extractMentions(body, tags, users);
fragments = extractLinks(fragments);
let fragments = extractMentions(frag);
fragments = extractLinks(fragments, frag.pref);
fragments = extractInvoices(fragments);
fragments = extractHashtags(fragments);
return fragments;
@ -178,7 +184,8 @@ export type Fragment = string | JSX.Element;
export interface TextFragment {
body: Fragment[],
tags: Tag[],
users: Map<string, MetadataCache>
users: Map<string, MetadataCache>,
pref: UserPreferences
}
export interface TextProps {
@ -188,11 +195,12 @@ export interface TextProps {
}
export default function Text({ content, tags, users }: TextProps) {
const pref = useSelector<RootState, UserPreferences>(s => s.login.preferences);
const components = useMemo(() => {
return {
p: (x: any) => transformParagraph({ body: x.children ?? [], tags, users }),
a: (x: any) => transformHttpLink(x.href),
li: (x: any) => transformLi({ body: x.children ?? [], tags, users }),
p: (x: any) => transformParagraph({ body: x.children ?? [], tags, users, pref }),
a: (x: any) => transformHttpLink(x.href, pref),
li: (x: any) => transformLi({ body: x.children ?? [], tags, users, pref }),
};
}, [content]);
return <ReactMarkdown className="text" components={components}>{content}</ReactMarkdown>

View File

@ -3,9 +3,13 @@ import { u256 } from "Nostr";
import EventKind from "Nostr/EventKind";
import { Subscriptions } from "Nostr/Subscriptions";
import useSubscription from "Feed/Subscription";
import { useSelector } from "react-redux";
import { RootState } from "State/Store";
import { UserPreferences } from "State/Login";
export default function useThreadFeed(id: u256) {
const [trackingEvents, setTrackingEvent] = useState<u256[]>([id]);
const pref = useSelector<RootState, UserPreferences>(s => s.login.preferences);
function addId(id: u256[]) {
setTrackingEvent((s) => {
@ -21,7 +25,7 @@ export default function useThreadFeed(id: u256) {
// get replies to this event
const subRelated = new Subscriptions();
subRelated.Kinds = new Set([EventKind.Reaction, EventKind.TextNote, EventKind.Deletion, EventKind.Repost]);
subRelated.Kinds = new Set(pref.enableReactions ? [EventKind.Reaction, EventKind.TextNote, EventKind.Deletion, EventKind.Repost] : [EventKind.TextNote]);
subRelated.ETags = thisSub.Ids;
thisSub.AddSubscription(subRelated);

View File

@ -4,6 +4,9 @@ import EventKind from "Nostr/EventKind";
import { Subscriptions } from "Nostr/Subscriptions";
import { unixNow } from "Util";
import useSubscription from "Feed/Subscription";
import { useSelector } from "react-redux";
import { RootState } from "State/Store";
import { UserPreferences } from "State/Login";
export interface TimelineFeedOptions {
method: "TIME_RANGE" | "LIMIT_UNTIL"
@ -20,6 +23,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
const [until, setUntil] = useState<number>(now);
const [since, setSince] = useState<number>(now - window);
const [trackingEvents, setTrackingEvent] = useState<u256[]>([]);
const pref = useSelector<RootState, UserPreferences>(s => s.login.preferences);
const sub = useMemo(() => {
if (subject.type !== "global" && subject.items.length == 0) {
@ -56,7 +60,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
const main = useSubscription(sub, { leaveOpen: true });
const subNext = useMemo(() => {
if (trackingEvents.length > 0) {
if (trackingEvents.length > 0 && pref.enableReactions) {
let sub = new Subscriptions();
sub.Id = `timeline-related:${subject.type}`;
sub.Kinds = new Set([EventKind.Reaction, EventKind.Deletion, EventKind.Repost]);

View File

@ -1,9 +1,15 @@
import ProfilePreview from "Element/ProfilePreview";
import ZapButton from "Element/ZapButton";
import { bech32ToHex } from "Util";
const Developers = [
"63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed", // kieran
"7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194" // verbiricha
bech32ToHex("npub1v0lxxxxutpvrelsksy8cdhgfux9l6a42hsj2qzquu2zk7vc9qnkszrqj49"), // kieran
bech32ToHex("npub107jk7htfv243u0x5ynn43scq9wrxtaasmrwwa8lfu2ydwag6cx2quqncxg") // verbiricha
];
const Contributors = [
bech32ToHex("npub10djxr5pvdu97rjkde7tgcsjxzpdzmdguwacfjwlchvj7t88dl7nsdl54nf"), // ivan
bech32ToHex("npub148jmlutaa49y5wl5mcll003ftj59v79vf7wuv3apcwpf75hx22vs7kk9ay"), // liran cohen
];
const DonatePage = () => {
@ -19,8 +25,10 @@ const DonatePage = () => {
<p>
Check out the code here: <a className="highlight" href="https://github.com/v0l/snort" rel="noreferrer" target="_blank">https://github.com/v0l/snort</a>
</p>
<h3>Developers</h3>
<h3>Primary Developers</h3>
{Developers.map(a => <ProfilePreview pubkey={a} key={a} actions={<ZapButton pubkey={a} />} />)}
<h4>Contributors</h4>
{Contributors.map(a => <ProfilePreview pubkey={a} key={a} actions={<ZapButton pubkey={a} />} />)}
</div>
);
}

View File

@ -6,7 +6,7 @@ import { faBell, faMessage } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { RootState } from "State/Store";
import { init } from "State/Login";
import { init, setPreferences, UserPreferences } from "State/Login";
import { HexKey, RawEvent, TaggedRawEvent } from "Nostr";
import { RelaySettings } from "Nostr/Connection";
import { System } from "Nostr/System"
@ -23,6 +23,7 @@ export default function Layout() {
const notifications = useSelector<RootState, TaggedRawEvent[]>(s => s.login.notifications);
const readNotifications = useSelector<RootState, number>(s => s.login.readNotifications);
const dms = useSelector<RootState, RawEvent[]>(s => s.login.dms);
const prefs = useSelector<RootState, UserPreferences>(s => s.login.preferences);
useLoginFeed();
useEffect(() => {
@ -38,6 +39,27 @@ export default function Layout() {
}
}, [relays]);
function setTheme(theme: "light" | "dark") {
const elm = document.documentElement;
if (theme === "light" && !elm.classList.contains("light")) {
elm.classList.add("light");
} else if (theme === "dark" && elm.classList.contains("light")) {
elm.classList.remove("light");
}
}
useEffect(() => {
let osTheme = window.matchMedia("(prefers-color-scheme: light)");
setTheme(prefs.theme === "system" && osTheme.matches ? "light" : prefs.theme === "light" ? "light" : "dark");
osTheme.onchange = (e) => {
if (prefs.theme === "system") {
setTheme(e.matches ? "light" : "dark");
}
}
return () => { osTheme.onchange = null; }
}, [prefs.theme]);
useEffect(() => {
dispatch(init());
}, []);

View File

@ -1,240 +1,35 @@
import "./SettingsPage.css";
import Nostrich from "nostrich.jpg";
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faShop } from "@fortawesome/free-solid-svg-icons";
import { RootState } from "State/Store";
import { logout, setRelays } from "State/Login";
import useEventPublisher from "Feed/EventPublisher";
import useProfile from "Feed/ProfileFeed";
import VoidUpload from "Feed/VoidUpload";
import { hexToBech32, openFile } from "Util";
import Relay from "Element/Relay";
import Copy from "Element/Copy";
import { HexKey, UserMetadata } from "Nostr";
import { RelaySettings } from "Nostr/Connection";
import { MetadataCache } from "Db/User";
import { Outlet, RouteObject, useNavigate } from "react-router-dom";
import SettingsIndex from "Pages/settings/Index";
import Profile from "Pages/settings/Profile";
import Relay from "Pages/settings/Relays";
import Preferences from "Pages/settings/Preferences";
export default function SettingsPage() {
const navigate = useNavigate();
const id = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
const privKey = useSelector<RootState, HexKey | undefined>(s => s.login.privateKey);
const relays = useSelector<RootState, Record<string, RelaySettings>>(s => s.login.relays);
const dispatch = useDispatch();
const user = useProfile(id)?.get(id || "");
const publisher = useEventPublisher();
const [name, setName] = useState<string>();
const [displayName, setDisplayName] = useState<string>();
const [picture, setPicture] = useState<string>();
const [banner, setBanner] = useState<string>();
const [about, setAbout] = useState<string>();
const [website, setWebsite] = useState<string>();
const [nip05, setNip05] = useState<string>();
const [lud06, setLud06] = useState<string>();
const [lud16, setLud16] = useState<string>();
const [newRelay, setNewRelay] = useState<string>();
const avatarPicture = (picture?.length ?? 0) === 0 ? Nostrich : picture
useEffect(() => {
if (user) {
setName(user.name);
setDisplayName(user.display_name)
setPicture(user.picture);
setBanner(user.banner);
setAbout(user.about);
setWebsite(user.website);
setNip05(user.nip05);
setLud06(user.lud06);
setLud16(user.lud16);
}
}, [user]);
async function saveProfile() {
// copy user object and delete internal fields
let userCopy = {
...user,
name,
display_name: displayName,
about,
picture,
banner,
website,
nip05,
lud16
};
delete userCopy["loaded"];
delete userCopy["created"];
delete userCopy["pubkey"];
console.debug(userCopy);
let ev = await publisher.metadata(userCopy);
console.debug(ev);
publisher.broadcast(ev);
}
async function uploadFile() {
let file = await openFile();
if (file) {
console.log(file);
let rsp = await VoidUpload(file, file.name);
if (!rsp?.ok) {
throw "Upload failed, please try again later";
}
return rsp.file;
}
}
async function setNewAvatar() {
const rsp = await uploadFile();
if (rsp) {
setPicture(rsp.meta?.url ?? `https://void.cat/d/${rsp.id}`);
}
}
async function setNewBanner() {
const rsp = await uploadFile();
if (rsp) {
setBanner(rsp.meta?.url ?? `https://void.cat/d/${rsp.id}`);
}
}
async function saveRelays() {
let ev = await publisher.saveRelays();
publisher.broadcast(ev);
}
function editor() {
return (
<div className="editor">
<div className="form-group">
<div>Name:</div>
<div>
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
</div>
</div>
<div className="form-group">
<div>Display name:</div>
<div>
<input type="text" value={displayName} onChange={(e) => setDisplayName(e.target.value)} />
</div>
</div>
<div className="form-group f-col">
<div>About:</div>
<div className="w-max">
<textarea className="w-max" onChange={(e) => setAbout(e.target.value)} value={about}></textarea>
</div>
</div>
<div className="form-group">
<div>Website:</div>
<div>
<input type="text" value={website} onChange={(e) => setWebsite(e.target.value)} />
</div>
</div>
<div className="form-group">
<div>NIP-05:</div>
<div>
<input type="text" className="mr10" value={nip05} onChange={(e) => setNip05(e.target.value)} />
<div className="btn" onClick={() => navigate("/verification")}>
<FontAwesomeIcon icon={faShop} />
&nbsp;
Buy
</div>
</div>
</div>
<div className="form-group">
<div>LN Address:</div>
<div>
<input type="text" value={lud16} onChange={(e) => setLud16(e.target.value)} />
</div>
</div>
<div className="form-group">
<div>
<div className="btn" onClick={() => { dispatch(logout()); navigate("/"); }}>Logout</div>
</div>
<div>
<div className="btn" onClick={() => saveProfile()}>Save</div>
</div>
</div>
</div>
)
}
function addNewRelay() {
if ((newRelay?.length ?? 0) > 0) {
const parsed = new URL(newRelay!);
const payload = {
relays: {
...relays,
[parsed.toString()]: { read: false, write: false }
},
createdAt: Math.floor(new Date().getTime() / 1000)
};
dispatch(setRelays(payload))
}
}
function addRelay() {
return (
<>
<h4>Add Relays</h4>
<div className="flex mb10">
<input type="text" className="f-grow" placeholder="wss://my-relay.com" value={newRelay} onChange={(e) => setNewRelay(e.target.value)} />
</div>
<div className="btn mb10" onClick={() => addNewRelay()}>Add</div>
</>
)
}
function settings() {
if (!id) return null;
return (
<>
<h1>Settings</h1>
<div className="flex f-center image-settings">
<div>
<h2>Avatar</h2>
<div style={{ backgroundImage: `url(${avatarPicture})` }} className="avatar">
<div className="edit" onClick={() => setNewAvatar()}>Edit</div>
</div>
</div>
<div>
<h2>Header</h2>
<div style={{ backgroundImage: `url(${(banner?.length ?? 0) === 0 ? Nostrich : banner})` }} className="banner">
<div className="edit" onClick={() => setNewBanner()}>Edit</div>
</div>
</div>
</div>
{editor()}
</>
)
}
return (
<div className="settings">
{settings()}
{privKey && (<div className="flex f-col bg-grey">
<div>
<h4>Private Key:</h4>
</div>
<div>
<Copy text={hexToBech32("nsec", privKey)} />
</div>
</div>)}
<h4>Relays</h4>
<div className="flex f-col">
{Object.keys(relays || {}).map(a => <Relay addr={a} key={a} />)}
</div>
<div className="flex actions">
<div className="f-grow"></div>
<div className="btn" onClick={() => saveRelays()}>Save</div>
</div>
{addRelay()}
</div>
<>
<h2 onClick={() => navigate("/settings")} className="pointer">Settings</h2>
<Outlet />
</>
);
}
export const SettingsRoutes: RouteObject[] = [
{
path: "",
element: <SettingsIndex />
},
{
path: "profile",
element: <Profile />
},
{
path: "relays",
element: <Relay />
},
{
path: "preferences",
element: <Preferences />
}
]

View File

@ -0,0 +1,3 @@
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
.settings-nav .card {
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
cursor: pointer;
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```
}
verbiricha commented 2023-01-20 17:42:09 +00:00 (Migrated from github.com)
Review
    background-color: var(--note-bg);
    cursor: pointer;
```suggestion background-color: var(--note-bg); cursor: pointer; ```

View File

@ -0,0 +1,31 @@
import { faCircleDollarToSlot, faGear, faPlug, faUser } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNavigate } from "react-router-dom";
import "./Index.css";
const SettingsIndex = () => {
const navigate = useNavigate();
return (
<div className="settings-nav">
<div className="card" onClick={() => navigate("profile")}>
<FontAwesomeIcon icon={faUser} size="xl" className="mr10" />
Profile
</div>
<div className="card" onClick={() => navigate("relays")}>
<FontAwesomeIcon icon={faPlug} size="xl" className="mr10" />
Relays
</div>
<div className="card" onClick={() => navigate("preferences")}>
<FontAwesomeIcon icon={faGear} size="xl" className="mr10" />
Preferences
</div>
<div className="card" onClick={() => navigate("/donate")}>
<FontAwesomeIcon icon={faCircleDollarToSlot} size="xl" className="mr10" />
Donate
</div>
</div>
)
}
export default SettingsIndex;

View File

@ -0,0 +1,8 @@
.preferences small {
margin-top: 0.5em;
color: var(--font-secondary-color);
}
.preferences select {
min-width: 100px;
}

View File

@ -0,0 +1,56 @@
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
import { useDispatch, useSelector } from "react-redux";
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
import { setPreferences, UserPreferences } from "State/Login";
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
import { RootState } from "State/Store";
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
import "./Preferences.css";
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
const PreferencesPage = () => {
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
const dispatch = useDispatch();
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
const perf = useSelector<RootState, UserPreferences>(s => s.login.preferences);
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
return (
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="preferences">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<h3>Preferences</h3>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="card flex">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="flex f-col f-grow">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>Theme</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<select value={perf.theme} onChange={e => dispatch(setPreferences({ ...perf, theme: e.target.value} as UserPreferences))}>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<option value="system">System (Default)</option>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<option value="light">Light</option>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<option value="dark">Dark</option>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</select>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="card flex">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="flex f-col f-grow">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>Automatically load media</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<small>Media in posts will automatically be shown, if disabled only the link will show</small>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<input type="checkbox" checked={perf.autoLoadMedia} onChange={e => dispatch(setPreferences({ ...perf, autoLoadMedia: e.target.checked }))} />
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="card flex">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="flex f-col f-grow">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>Enable reactions</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<small>Reactions will be shown on every page, if disabled no reactions will be shown</small>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<input type="checkbox" checked={perf.enableReactions} onChange={e => dispatch(setPreferences({ ...perf, enableReactions: e.target.checked }))} />
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="card flex">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div className="flex f-col f-grow">
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>Confirm reposts</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<small>Reposts need to be manually confirmed</small>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
<input type="checkbox" checked={perf.confirmReposts} onChange={e => dispatch(setPreferences({ ...perf, confirmReposts: e.target.checked }))} />
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
</div>
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
)
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
}
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.
export default PreferencesPage;
verbiricha commented 2023-01-20 17:49:00 +00:00 (Migrated from github.com)
Review

Wdyt about keeping current default (use system theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences.

This would be similar to other preferences, keeping the current default but offering customization.

Wdyt about keeping current default (use `system` theme)? If user explicitly sets a theme we can override it but if not use system theme. Have my devices configured to use dark/light depending on time of the day, don't want to be manually changing it from preferences. This would be similar to other preferences, keeping the current default but offering customization.

View File

@ -1,4 +1,4 @@
import "./SettingsPage.css";
import "./Profile.css";
import Nostrich from "nostrich.jpg";
import { useEffect, useState } from "react";
@ -10,20 +10,16 @@ import { faShop } from "@fortawesome/free-solid-svg-icons";
import useEventPublisher from "Feed/EventPublisher";
import useProfile from "Feed/ProfileFeed";
import VoidUpload from "Feed/VoidUpload";
import { logout, setRelays } from "State/Login";
import { logout } from "State/Login";
import { hexToBech32, openFile } from "Util";
import Relay from "Element/Relay";
import Copy from "Element/Copy";
import { RootState } from "State/Store";
import { HexKey, UserMetadata } from "Nostr";
import { RelaySettings } from "Nostr/Connection";
import { MetadataCache } from "Db/User";
import { HexKey } from "Nostr";
export default function SettingsPage() {
export default function ProfileSettings() {
const navigate = useNavigate();
const id = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
const privKey = useSelector<RootState, HexKey | undefined>(s => s.login.privateKey);
const relays = useSelector<RootState, Record<string, RelaySettings>>(s => s.login.relays);
const dispatch = useDispatch();
const user = useProfile(id)?.get(id || "");
const publisher = useEventPublisher();
@ -37,7 +33,6 @@ export default function SettingsPage() {
const [nip05, setNip05] = useState<string>();
const [lud06, setLud06] = useState<string>();
const [lud16, setLud16] = useState<string>();
const [newRelay, setNewRelay] = useState<string>();
const avatarPicture = (picture?.length ?? 0) === 0 ? Nostrich : picture
@ -104,11 +99,6 @@ export default function SettingsPage() {
}
}
async function saveRelays() {
let ev = await publisher.saveRelays();
publisher.broadcast(ev);
}
function editor() {
return (
<div className="editor">
@ -165,37 +155,10 @@ export default function SettingsPage() {
)
}
function addNewRelay() {
if ((newRelay?.length ?? 0) > 0) {
const parsed = new URL(newRelay!);
const payload = {
relays: {
...relays,
[parsed.toString()]: { read: false, write: false }
},
createdAt: Math.floor(new Date().getTime() / 1000)
};
dispatch(setRelays(payload))
}
}
function addRelay() {
return (
<>
<h4>Add Relays</h4>
<div className="flex mb10">
<input type="text" className="f-grow" placeholder="wss://my-relay.com" value={newRelay} onChange={(e) => setNewRelay(e.target.value)} />
</div>
<div className="btn mb10" onClick={() => addNewRelay()}>Add</div>
</>
)
}
function settings() {
if (!id) return null;
return (
<>
<h1>Settings</h1>
<div className="flex f-center image-settings">
<div>
<h2>Avatar</h2>
@ -217,6 +180,7 @@ export default function SettingsPage() {
return (
<div className="settings">
<h3>Profile</h3>
{settings()}
{privKey && (<div className="flex f-col bg-grey">
<div>
@ -226,15 +190,6 @@ export default function SettingsPage() {
<Copy text={hexToBech32("nsec", privKey)} />
</div>
</div>)}
<h4>Relays</h4>
<div className="flex f-col">
{Object.keys(relays || {}).map(a => <Relay addr={a} key={a} />)}
</div>
<div className="flex actions">
<div className="f-grow"></div>
<div className="btn" onClick={() => saveRelays()}>Save</div>
</div>
{addRelay()}
</div>
);
}

View File

@ -0,0 +1,63 @@
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import Relay from "Element/Relay";
import useEventPublisher from "Feed/EventPublisher";
import { RootState } from "State/Store";
import { RelaySettings } from "Nostr/Connection";
import { setRelays } from "State/Login";
const RelaySettingsPage = () => {
const dispatch = useDispatch();
const publisher = useEventPublisher();
const relays = useSelector<RootState, Record<string, RelaySettings>>(s => s.login.relays);
const [newRelay, setNewRelay] = useState<string>();
async function saveRelays() {
let ev = await publisher.saveRelays();
publisher.broadcast(ev);
}
function addRelay() {
return (
<>
<h4>Add Relays</h4>
<div className="flex mb10">
<input type="text" className="f-grow" placeholder="wss://my-relay.com" value={newRelay} onChange={(e) => setNewRelay(e.target.value)} />
</div>
<div className="btn mb10" onClick={() => addNewRelay()}>Add</div>
</>
)
}
function addNewRelay() {
if ((newRelay?.length ?? 0) > 0) {
const parsed = new URL(newRelay!);
const payload = {
relays: {
...relays,
[parsed.toString()]: { read: false, write: false }
},
createdAt: Math.floor(new Date().getTime() / 1000)
};
dispatch(setRelays(payload))
}
}
return (
<>
<h3>Relays</h3>
<div className="flex f-col">
{Object.keys(relays || {}).map(a => <Relay addr={a} key={a} />)}
</div>
<div className="flex actions">
<div className="f-grow"></div>
<div className="btn" onClick={() => saveRelays()}>Save</div>
</div>
{addRelay()}
</>
)
}
export default RelaySettingsPage;

View File

@ -3,12 +3,36 @@ import * as secp from '@noble/secp256k1';
import { DefaultRelays } from 'Const';
import { HexKey, RawEvent, TaggedRawEvent } from 'Nostr';
import { RelaySettings } from 'Nostr/Connection';
import { useDispatch } from 'react-redux';
const PrivateKeyItem = "secret";
const PublicKeyItem = "pubkey";
const NotificationsReadItem = "notifications-read";
const UserPreferencesKey = "preferences";
interface LoginStore {
export interface UserPreferences {
/**
* Enable reactions / reposts / zaps
*/
enableReactions: boolean,
/**
* Automatically load media (show link only) (bandwidth/privacy)
*/
autoLoadMedia: boolean,
/**
* Select between light/dark theme
*/
theme: "system" | "light" | "dark",
/**
* Ask for confirmation when reposting notes
*/
confirmReposts: boolean
}
export interface LoginStore {
/**
* If there is no login
*/
@ -57,7 +81,12 @@ interface LoginStore {
/**
* Counter to trigger refresh of unread dms
*/
dmInteraction: 0
dmInteraction: 0,
/**
* Users cusom preferences
*/
preferences: UserPreferences
};
const InitState = {
@ -70,7 +99,13 @@ const InitState = {
notifications: [],
readNotifications: new Date().getTime(),
dms: [],
dmInteraction: 0
dmInteraction: 0,
preferences: {
enableReactions: true,
autoLoadMedia: true,
theme: "system",
confirmReposts: false
}
} as LoginStore;
export interface SetRelaysPayload {
@ -106,6 +141,12 @@ const LoginSlice = createSlice({
if (!isNaN(readNotif)) {
state.readNotifications = readNotif;
}
// preferences
let pref = window.localStorage.getItem(UserPreferencesKey);
if (pref) {
state.preferences = JSON.parse(pref);
}
},
setPrivateKey: (state, action: PayloadAction<HexKey>) => {
state.loggedOut = false;
@ -205,6 +246,10 @@ const LoginSlice = createSlice({
markNotificationsRead: (state) => {
state.readNotifications = new Date().getTime();
window.localStorage.setItem(NotificationsReadItem, state.readNotifications.toString());
},
setPreferences: (state, action: PayloadAction<UserPreferences>) => {
state.preferences = action.payload;
window.localStorage.setItem(UserPreferencesKey, JSON.stringify(state.preferences));
}
}
});
@ -220,6 +265,7 @@ export const {
addDirectMessage,
incDmInteraction,
logout,
markNotificationsRead
markNotificationsRead,
setPreferences
} = LoginSlice.actions;
export const reducer = LoginSlice.reducer;

View File

@ -1,53 +1,51 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap');
:root {
--bg-color: #000;
--font-color: #FFF;
--font-secondary-color: #555;
--font-tertiary-color: #666;
--font-size: 16px;
--font-size-small: 14px;
--font-size-tiny: 12px;
--modal-bg-color: rgba(0,0,0, 0.8);
--note-bg: #111;
--highlight-light: #ffd342;
--highlight: #ffc400;
--highlight-dark: #dba800;
--error: #FF6053;
--success: #2AD544;
--bg-color: #000;
--font-color: #FFF;
--font-secondary-color: #555;
--font-tertiary-color: #666;
--font-size: 16px;
--font-size-small: 14px;
--font-size-tiny: 12px;
--modal-bg-color: rgba(0, 0, 0, 0.8);
--note-bg: #111;
--highlight-light: #ffd342;
--highlight: #ffc400;
--highlight-dark: #dba800;
--error: #FF6053;
--success: #2AD544;
--gray-superlight: #EEE;
--gray-light: #999;
--gray-medium: #666;
--gray: #333;
--gray-secondary: #222;
--gray-tertiary: #444;
--gray-gradient: linear-gradient(to bottom right, var(--gray-superlight), var(--gray), var(--gray-light));
--snort-gradient: linear-gradient(to bottom right, var(--highlight-light), var(--highlight), var(--highlight-dark));
--nostrplebs-gradient: linear-gradient(to bottom right, #ff3cac, #2b86c5);
--strike-army-gradient: linear-gradient(to bottom right, #CCFF00, #a1c900);
--gray-superlight: #EEE;
--gray-light: #999;
--gray-medium: #666;
--gray: #333;
--gray-secondary: #222;
--gray-tertiary: #444;
--gray-gradient: linear-gradient(to bottom right, var(--gray-superlight), var(--gray), var(--gray-light));
--snort-gradient: linear-gradient(to bottom right, var(--highlight-light), var(--highlight), var(--highlight-dark));
--nostrplebs-gradient: linear-gradient(to bottom right, #ff3cac, #2b86c5);
--strike-army-gradient: linear-gradient(to bottom right, #CCFF00, #a1c900);
}
@media (prefers-color-scheme: light) {
:root {
--bg-color: #F1F1F1;
--font-color: #57534E;
--font-secondary-color: #B9B9B9;
--font-tertiary-color: #F3F3F3;
html.light {
--bg-color: #F1F1F1;
--font-color: #57534E;
--font-secondary-color: #B9B9B9;
--font-tertiary-color: #F3F3F3;
--highlight-light: #16AAC1;
--highlight: #0284C7;
--highlight-dark: #0A52B5;
--modal-bg-color: rgba(240, 240, 240, 0.8);
--highlight-light: #16AAC1;
--highlight: #0284C7;
--highlight-dark: #0A52B5;
--modal-bg-color: rgba(240, 240, 240, 0.8);
--note-bg: white;
--note-bg: white;
--gray: #CCC;
--gray-secondary: #DDD;
--gray-tertiary: #EEE;
--gray-superlight: #333;
--gray-light: #555;
}
--gray: #CCC;
--gray-secondary: #DDD;
--gray-tertiary: #EEE;
--gray-superlight: #333;
--gray-light: #555;
}
body {
@ -70,18 +68,18 @@ code {
margin-right: auto;
}
.page > .header {
.page>.header {
display: flex;
align-items: center;
margin: 10px 0;
}
.page > .header > div:nth-child(1) {
.page>.header>div:nth-child(1) {
font-size: x-large;
flex-grow: 1;
}
.page > .header > div:nth-child(2) {
.page>.header>div:nth-child(2) {
display: flex;
align-items: center;
}
@ -92,28 +90,32 @@ code {
background-color: var(--note-bg);
padding: 6px 12px;
}
@media (min-width: 720px) {
.card { margin-bottom: 24px; padding: 12px 24px; }
}
@media (prefers-color-scheme: light) {
.card {
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.05);
margin-bottom: 24px;
padding: 12px 24px;
}
}
html.light .card {
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.05);
}
.card .header {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.card > .footer {
.card>.footer {
display: flex;
flex-direction: row-reverse;
margin-top: 12px;
}
.btn {
.btn {
padding: 10px;
border-radius: 5px;
cursor: pointer;
@ -135,7 +137,7 @@ code {
.btn.active {
border: 2px solid;
background-color: var(--gray-secondary);
color: var(--font-color);
color: var(--font-color);
font-weight: bold;
}
@ -167,9 +169,14 @@ input[type="text"], input[type="password"], input[type="number"], textarea, sele
color: var(--font-color);
}
input[type="checkbox"] {
width: 24px;
height: 24px;
}
input:disabled {
color: var(--gray-medium);
cursor:not-allowed;
cursor: not-allowed;
}
textarea:placeholder {
@ -244,22 +251,22 @@ div.form-group {
align-items: center;
}
div.form-group > div {
div.form-group>div {
padding: 3px 5px;
word-break: break-word;
}
div.form-group > div:nth-child(1) {
div.form-group>div:nth-child(1) {
min-width: 100px;
}
div.form-group > div:nth-child(2) {
div.form-group>div:nth-child(2) {
display: flex;
flex-grow: 1;
justify-content: end;
}
div.form-group > div:nth-child(2) input {
div.form-group>div:nth-child(2) input {
flex-grow: 1;
}
@ -269,7 +276,7 @@ div.form-group > div:nth-child(2) input {
height: 100vh;
top: 0;
left: 0;
background-color: rgba(0,0,0,0.8);
background-color: rgba(0, 0, 0, 0.8);
}
.modal .modal-content {
@ -277,7 +284,7 @@ div.form-group > div:nth-child(2) input {
justify-content: center;
}
.modal .modal-content > div {
.modal .modal-content>div {
padding: 10px;
border-radius: 10px;
background-color: var(--gray);
@ -321,12 +328,12 @@ body.scroll-lock {
overflow-x: auto;
}
.tabs > div {
.tabs>div {
margin-right: 10px;
cursor: pointer;
}
.tabs > div:last-child {
.tabs>div:last-child {
margin: 0;
}
@ -347,44 +354,48 @@ body.scroll-lock {
}
.root-tabs {
padding: 0;
align-items: center;
justify-content: flex-start;
padding: 0;
align-items: center;
justify-content: flex-start;
}
.root-tab {
border-bottom: 3px solid var(--gray-secondary);
border-bottom: 3px solid var(--gray-secondary);
}
.root-tab.active {
border-bottom: 3px solid var(--highlight);
border-bottom: 3px solid var(--highlight);
}
.tweet {
display: flex;
align-items: center;
justify-content: center;
display: flex;
align-items: center;
justify-content: center;
}
.tweet div {
width: 100%;
width: 100%;
}
.tweet div .twitter-tweet {
margin: 0 auto;
margin: 0 auto;
}
.tweet div .twitter-tweet > iframe {
max-height: unset;
.tweet div .twitter-tweet>iframe {
max-height: unset;
}
@media(max-width: 720px) {
.page {
width: calc(100vw - 8px);
}
div.form-group {
flex-direction: column;
align-items: flex-start;
}
}
.highlight { color: var(--highlight); }
.highlight {
color: var(--highlight);
}

View File

@ -19,7 +19,7 @@ import ProfilePage from 'Pages/ProfilePage';
import RootPage from 'Pages/Root';
import NotificationsPage from 'Pages/Notifications';
import NewUserPage from 'Pages/NewUserPage';
import SettingsPage from 'Pages/SettingsPage';
import SettingsPage, { SettingsRoutes } from 'Pages/SettingsPage';
import ErrorPage from 'Pages/ErrorPage';
import VerificationPage from 'Pages/Verification';
import MessagesPage from 'Pages/MessagesPage';
@ -65,7 +65,8 @@ const router = createBrowserRouter([
},
{
path: "/settings",
element: <SettingsPage />
element: <SettingsPage />,
children: SettingsRoutes
},
{
path: "/verification",