readonly login sessions

This commit is contained in:
2023-09-23 22:21:37 +01:00
parent 3efb5321f6
commit 94da60ebfa
30 changed files with 217 additions and 119 deletions

View File

@ -66,13 +66,14 @@ export default function Layout() {
const NoteCreatorButton = () => {
const location = useLocation();
const { readonly } = useLogin(s => ({ readonly: s.readonly }));
const { show, replyTo, update } = useNoteCreator(v => ({ show: v.show, replyTo: v.replyTo, update: v.update }));
const shouldHideNoteCreator = useMemo(() => {
const isReplyNoteCreatorShowing = replyTo && show;
const hideOn = ["/settings", "/messages", "/new", "/login", "/donate", "/e", "/subscribe"];
return isReplyNoteCreatorShowing || hideOn.some(a => location.pathname.startsWith(a));
}, [location]);
return readonly || isReplyNoteCreatorShowing || hideOn.some(a => location.pathname.startsWith(a));
}, [location, readonly]);
if (shouldHideNoteCreator) return;
return (
@ -96,7 +97,12 @@ const AccountHeader = () => {
const navigate = useNavigate();
const { formatMessage } = useIntl();
const { publicKey, latestNotification, readNotifications } = useLogin();
const { publicKey, latestNotification, readNotifications, readonly } = useLogin(s => ({
publicKey: s.publicKey,
latestNotification: s.latestNotification,
readNotifications: s.readNotifications,
readonly: s.readonly,
}));
const profile = useUserProfile(publicKey);
const [search, setSearch] = useState("");
const [searching, setSearching] = useState(false);
@ -174,10 +180,12 @@ const AccountHeader = () => {
)}
</div>
)}
<Link className="btn" to="/messages">
<Icon name="mail" size={24} />
{unreadDms > 0 && <span className="has-unread"></span>}
</Link>
{!readonly && (
<Link className="btn" to="/messages">
<Icon name="mail" size={24} />
{unreadDms > 0 && <span className="has-unread"></span>}
</Link>
)}
<Link className="btn" to="/notifications" onClick={goToNotifications}>
<Icon name="bell-02" size={24} />
{hasNotifications && <span className="has-unread"></span>}

View File

@ -97,6 +97,7 @@ export default function LoginPage() {
async function doLogin(pin?: string) {
try {
await loginHandler.doLogin(key, pin);
navigate("/");
} catch (e) {
if (e instanceof PinRequiredError) {
setPin(true);

View File

@ -466,7 +466,7 @@ export default function ProfilePage() {
<Icon name="zap" size={16} />
</IconButton>
)}
{loginPubKey && (
{loginPubKey && !login.readonly && (
<>
<IconButton
onClick={() =>

View File

@ -22,7 +22,7 @@ export interface ProfileSettingsProps {
export default function ProfileSettings(props: ProfileSettingsProps) {
const navigate = useNavigate();
const { publicKey: id } = useLogin();
const { publicKey: id, readonly } = useLogin(s => ({ publicKey: s.publicKey, readonly: s.readonly }));
const user = useUserProfile(id ?? "");
const publisher = useEventPublisher();
const uploader = useFileUpload();
@ -113,26 +113,48 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
<h4>
<FormattedMessage defaultMessage="Name" />
</h4>
<input className="w-max" type="text" value={name} onChange={e => setName(e.target.value)} />
<input
className="w-max"
type="text"
value={name}
onChange={e => setName(e.target.value)}
disabled={readonly}
/>
</div>
<div className="flex f-col w-max g8">
<h4>
<FormattedMessage defaultMessage="About" />
</h4>
<textarea className="w-max" onChange={e => setAbout(e.target.value)} value={about}></textarea>
<textarea
className="w-max"
onChange={e => setAbout(e.target.value)}
value={about}
disabled={readonly}></textarea>
</div>
<div className="flex f-col w-max g8">
<h4>
<FormattedMessage defaultMessage="Website" />
</h4>
<input className="w-max" type="text" value={website} onChange={e => setWebsite(e.target.value)} />
<input
className="w-max"
type="text"
value={website}
onChange={e => setWebsite(e.target.value)}
disabled={readonly}
/>
</div>
<div className="flex f-col w-max g8">
<h4>
<FormattedMessage defaultMessage="Nostr Address" />
</h4>
<div className="flex f-col g8 w-max">
<input type="text" className="w-max" value={nip05} onChange={e => setNip05(e.target.value)} />
<input
type="text"
className="w-max"
value={nip05}
onChange={e => setNip05(e.target.value)}
disabled={readonly}
/>
<small>
<FormattedMessage defaultMessage="Usernames are not unique on Nostr. The nostr address is your unique human-readable address that is unique to you upon registration." />
</small>
@ -150,9 +172,15 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
<h4>
<FormattedMessage defaultMessage="Lightning Address" />
</h4>
<input className="w-max" type="text" value={lud16} onChange={e => setLud16(e.target.value)} />
<input
className="w-max"
type="text"
value={lud16}
onChange={e => setLud16(e.target.value)}
disabled={readonly}
/>
</div>
<AsyncButton className="primary" onClick={() => saveProfile()}>
<AsyncButton className="primary" onClick={() => saveProfile()} disabled={readonly}>
<FormattedMessage defaultMessage="Save" />
</AsyncButton>
</div>
@ -170,7 +198,7 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
background: (banner?.length ?? 0) > 0 ? `no-repeat center/cover url("${banner}")` : undefined,
}}
className="banner">
<AsyncButton type="button" onClick={() => setNewBanner()}>
<AsyncButton type="button" onClick={() => setNewBanner()} disabled={readonly}>
<FormattedMessage defaultMessage="Upload" />
</AsyncButton>
</div>
@ -178,7 +206,7 @@ export default function ProfileSettings(props: ProfileSettingsProps) {
{(props.avatar ?? true) && (
<div className="avatar-stack">
<Avatar pubkey={id} user={user} image={picture} />
<AsyncButton type="button" className="btn-rnd" onClick={() => setNewAvatar()}>
<AsyncButton type="button" className="btn-rnd" onClick={() => setNewAvatar()} disabled={readonly}>
<Icon name="upload-01" />
</AsyncButton>
</div>

View File

@ -8,6 +8,7 @@ import useEventPublisher from "Hooks/useEventPublisher";
import { System } from "index";
import useLogin from "Hooks/useLogin";
import { setRelays } from "Login";
import AsyncButton from "Element/AsyncButton";
import messages from "./messages";
@ -91,9 +92,9 @@ const RelaySettingsPage = () => {
</div>
<div className="flex mt10">
<div className="f-grow"></div>
<button type="button" onClick={() => saveRelays()}>
<AsyncButton type="button" onClick={() => saveRelays()} disabled={login.readonly}>
<FormattedMessage {...messages.Save} />
</button>
</AsyncButton>
</div>
{addRelay()}
<h3>