Rebranding features #636
1
packages/app/config/README.md
Normal file
1
packages/app/config/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Choose config with NODE_CONFIG_ENV: `NODE_CONFIG_ENV=iris yarn start`
|
7
packages/app/config/default.json
Normal file
7
packages/app/config/default.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"appName": "Snort",
|
||||||
|
"appNameCapitalized": "Snort",
|
||||||
|
"appTitle": "Snort - Nostr",
|
||||||
|
"nip05Domain": "snort.social",
|
||||||
|
"favicon": "public/favicon.ico"
|
||||||
|
}
|
7
packages/app/config/iris.json
Normal file
7
packages/app/config/iris.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"appName": "iris",
|
||||||
|
"appNameCapitalized": "Iris",
|
||||||
|
"appTitle": "iris",
|
||||||
|
"nip05Domain": "iris.to",
|
||||||
|
"favicon": "public/iris.ico"
|
||||||
|
}
|
@ -88,6 +88,7 @@
|
|||||||
"@webpack-cli/generators": "^3.0.4",
|
"@webpack-cli/generators": "^3.0.4",
|
||||||
"@webscopeio/react-textarea-autocomplete": "^4.9.2",
|
"@webscopeio/react-textarea-autocomplete": "^4.9.2",
|
||||||
"babel-loader": "^9.1.3",
|
"babel-loader": "^9.1.3",
|
||||||
|
"config": "^3.3.9",
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
"copy-webpack-plugin": "^11.0.0",
|
||||||
"css-loader": "^6.7.3",
|
"css-loader": "^6.7.3",
|
||||||
"css-minimizer-webpack-plugin": "^5.0.0",
|
"css-minimizer-webpack-plugin": "^5.0.0",
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<link rel="preconnect" href="https://imgproxy.snort.social" />
|
<link rel="preconnect" href="https://imgproxy.snort.social" />
|
||||||
<link rel="apple-touch-icon" href="/nostrich_512.png" />
|
<link rel="apple-touch-icon" href="/nostrich_512.png" />
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
<title>Snort - Nostr</title>
|
<title><%= htmlWebpackPlugin.options.templateParameters.appTitle %></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
BIN
packages/app/public/iris.ico
Normal file
BIN
packages/app/public/iris.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -6,6 +6,7 @@ interface AsyncButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>
|
|||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onClick(e: React.MouseEvent): Promise<void> | void;
|
onClick(e: React.MouseEvent): Promise<void> | void;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
ref?: React.Ref<HTMLButtonElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AsyncButton(props: AsyncButtonProps) {
|
export default function AsyncButton(props: AsyncButtonProps) {
|
||||||
@ -28,7 +29,7 @@ export default function AsyncButton(props: AsyncButtonProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button className="spinner-button" type="button" disabled={loading || props.disabled} {...props} onClick={handle}>
|
<button ref={props.ref} className="spinner-button" type="button" disabled={loading || props.disabled} {...props} onClick={handle}>
|
||||||
<span style={{ visibility: loading ? "hidden" : "visible" }}>{props.children}</span>
|
<span style={{ visibility: loading ? "hidden" : "visible" }}>{props.children}</span>
|
||||||
{loading && (
|
{loading && (
|
||||||
<span className="spinner-wrapper">
|
<span className="spinner-wrapper">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import "./BadgeList.css";
|
import "./BadgeList.css";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
import { TaggedNostrEvent } from "@snort/system";
|
import { TaggedNostrEvent } from "@snort/system";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { HexKey } from "@snort/system";
|
import { HexKey } from "@snort/system";
|
||||||
import useModeration from "Hooks/useModeration";
|
import useModeration from "Hooks/useModeration";
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useState, useMemo, ChangeEvent } from "react";
|
import { useState, useMemo, ChangeEvent } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { HexKey, TaggedNostrEvent } from "@snort/system";
|
import { HexKey, TaggedNostrEvent } from "@snort/system";
|
||||||
|
|
||||||
import Note from "Element/Note";
|
import Note from "Element/Note";
|
||||||
|
@ -6,7 +6,7 @@ import DM from "Element/DM";
|
|||||||
import useLogin from "Hooks/useLogin";
|
import useLogin from "Hooks/useLogin";
|
||||||
import WriteMessage from "Element/WriteMessage";
|
import WriteMessage from "Element/WriteMessage";
|
||||||
import { Chat, createEmptyChatObject, useChatSystem } from "chat";
|
import { Chat, createEmptyChatObject, useChatSystem } from "chat";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { ChatParticipantProfile } from "./ChatParticipant";
|
import { ChatParticipantProfile } from "./ChatParticipant";
|
||||||
|
|
||||||
export default function DmWindow({ id }: { id: string }) {
|
export default function DmWindow({ id }: { id: string }) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import "./FollowButton.css";
|
import "./FollowButton.css";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { HexKey } from "@snort/system";
|
import { HexKey } from "@snort/system";
|
||||||
|
|
||||||
import useEventPublisher from "Hooks/useEventPublisher";
|
import useEventPublisher from "Hooks/useEventPublisher";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { HexKey } from "@snort/system";
|
import { HexKey } from "@snort/system";
|
||||||
|
|
||||||
import useEventPublisher from "Hooks/useEventPublisher";
|
import useEventPublisher from "Hooks/useEventPublisher";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import "./Following.css";
|
import "./Following.css";
|
||||||
import useLogin from "Hooks/useLogin";
|
import useLogin from "Hooks/useLogin";
|
||||||
import Icon from "Icons/Icon";
|
import Icon from "Icons/Icon";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
export function FollowingMark({ pubkey }: { pubkey: string }) {
|
export function FollowingMark({ pubkey }: { pubkey: string }) {
|
||||||
const { follows } = useLogin(s => ({ follows: s.follows }));
|
const { follows } = useLogin(s => ({ follows: s.follows }));
|
||||||
|
22
packages/app/src/Element/FormattedMessage.tsx
Normal file
22
packages/app/src/Element/FormattedMessage.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { useState, useEffect, FC, ComponentProps } from 'react';
|
||||||
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
type ExtendedProps = ComponentProps<typeof FormattedMessage>;
|
||||||
|
|
||||||
|
const ExtendedFormattedMessage: FC<ExtendedProps> = (props) => {
|
||||||
|
const { id, defaultMessage, values} = props;
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
const [processedMessage, setProcessedMessage] = useState<string | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const translatedMessage = formatMessage({ id, defaultMessage }, values);
|
||||||
|
if (typeof translatedMessage === 'string') {
|
||||||
|
setProcessedMessage(translatedMessage.replace('Snort', process.env.APP_NAME_CAPITALIZED || 'Snort'));
|
||||||
|
}
|
||||||
|
}, [id, defaultMessage, values, formatMessage]);
|
||||||
|
|
||||||
|
return <>{processedMessage}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ExtendedFormattedMessage;
|
@ -1,5 +1,5 @@
|
|||||||
import { NostrEvent, NostrLink } from "@snort/system";
|
import { NostrEvent, NostrLink } from "@snort/system";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import { findTag } from "SnortUtils";
|
import { findTag } from "SnortUtils";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useInView } from "react-intersection-observer";
|
import { useInView } from "react-intersection-observer";
|
||||||
|
|
||||||
import messages from "./messages";
|
import messages from "./messages";
|
||||||
|
@ -4,7 +4,7 @@ const Logo = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
return (
|
return (
|
||||||
<h1 className="logo" onClick={() => navigate("/")}>
|
<h1 className="logo" onClick={() => navigate("/")}>
|
||||||
Snort
|
{process.env.APP_NAME}
|
||||||
</h1>
|
</h1>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { logout } from "Login";
|
import { logout } from "Login";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
import { Magnet } from "SnortUtils";
|
import { Magnet } from "SnortUtils";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { HexKey } from "@snort/system";
|
import { HexKey } from "@snort/system";
|
||||||
import useModeration from "Hooks/useModeration";
|
import useModeration from "Hooks/useModeration";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { HexKey } from "@snort/system";
|
import { HexKey } from "@snort/system";
|
||||||
import MuteButton from "Element/MuteButton";
|
import MuteButton from "Element/MuteButton";
|
||||||
import ProfilePreview from "Element/ProfilePreview";
|
import ProfilePreview from "Element/ProfilePreview";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { NostrEvent, NostrLink } from "@snort/system";
|
import { NostrEvent, NostrLink } from "@snort/system";
|
||||||
|
|
||||||
import { findTag } from "SnortUtils";
|
import { findTag } from "SnortUtils";
|
||||||
|
@ -7,7 +7,7 @@ import Note from "Element/Note";
|
|||||||
import { getDisplayName } from "Element/ProfileImage";
|
import { getDisplayName } from "Element/ProfileImage";
|
||||||
import { eventLink, hexToBech32 } from "SnortUtils";
|
import { eventLink, hexToBech32 } from "SnortUtils";
|
||||||
import useModeration from "Hooks/useModeration";
|
import useModeration from "Hooks/useModeration";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import Icon from "Icons/Icon";
|
import Icon from "Icons/Icon";
|
||||||
import { useUserProfile } from "@snort/system-react";
|
import { useUserProfile } from "@snort/system-react";
|
||||||
import { useInView } from "react-intersection-observer";
|
import { useInView } from "react-intersection-observer";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./NoteToSelf.css";
|
import "./NoteToSelf.css";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { profileLink } from "SnortUtils";
|
import { profileLink } from "SnortUtils";
|
||||||
|
|
||||||
import messages from "./messages";
|
import messages from "./messages";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import useLogin from "Hooks/useLogin";
|
import useLogin from "Hooks/useLogin";
|
||||||
import "./PinPrompt.css";
|
import "./PinPrompt.css";
|
||||||
import { ReactNode, useState } from "react";
|
import {ReactNode, useRef, useState} from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import { unwrap } from "@snort/shared";
|
import { unwrap } from "@snort/shared";
|
||||||
import { EventPublisher, InvalidPinError, PinEncrypted, PinEncryptedPayload } from "@snort/system";
|
import { EventPublisher, InvalidPinError, PinEncrypted, PinEncryptedPayload } from "@snort/system";
|
||||||
@ -23,6 +23,7 @@ export function PinPrompt({
|
|||||||
const [pin, setPin] = useState("");
|
const [pin, setPin] = useState("");
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
const submitButtonRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
async function submitPin() {
|
async function submitPin() {
|
||||||
if (pin.length < 4) {
|
if (pin.length < 4) {
|
||||||
@ -55,29 +56,38 @@ export function PinPrompt({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal id="pin" onClose={() => onCancel()}>
|
<Modal id="pin" onClose={() => onCancel()}>
|
||||||
<div className="flex-column g12">
|
<form
|
||||||
<h2>
|
onSubmit={(e) => {
|
||||||
<FormattedMessage defaultMessage="Enter Pin" />
|
e.preventDefault();
|
||||||
</h2>
|
if (submitButtonRef.current) {
|
||||||
{subTitle}
|
submitButtonRef.current.click();
|
||||||
<input
|
}
|
||||||
type="number"
|
}}
|
||||||
onChange={e => setPin(e.target.value)}
|
>
|
||||||
value={pin}
|
<div className="flex-column g12">
|
||||||
autoFocus={true}
|
<h2>
|
||||||
maxLength={20}
|
<FormattedMessage defaultMessage="Enter Pin" />
|
||||||
minLength={4}
|
</h2>
|
||||||
/>
|
{subTitle}
|
||||||
{error && <b className="error">{error}</b>}
|
<input
|
||||||
<div className="flex g8">
|
type="number"
|
||||||
<button type="button" onClick={() => onCancel()}>
|
onChange={(e) => setPin(e.target.value)}
|
||||||
<FormattedMessage defaultMessage="Cancel" />
|
value={pin}
|
||||||
</button>
|
autoFocus={true}
|
||||||
<AsyncButton type="button" onClick={() => submitPin()}>
|
maxLength={20}
|
||||||
<FormattedMessage defaultMessage="Submit" />
|
minLength={4}
|
||||||
</AsyncButton>
|
/>
|
||||||
|
{error && <b className="error">{error}</b>}
|
||||||
|
<div className="flex g8">
|
||||||
|
<button type="button" onClick={() => onCancel()}>
|
||||||
|
<FormattedMessage defaultMessage="Cancel" />
|
||||||
|
</button>
|
||||||
|
<AsyncButton ref={submitButtonRef} onClick={() => submitPin()} type="submit">
|
||||||
|
<FormattedMessage defaultMessage="Submit" />
|
||||||
|
</AsyncButton>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import useImgProxy from "Hooks/useImgProxy";
|
import useImgProxy from "Hooks/useImgProxy";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { getUrlHostname } from "SnortUtils";
|
import { getUrlHostname } from "SnortUtils";
|
||||||
|
|
||||||
interface ProxyImgProps extends React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement> {
|
interface ProxyImgProps extends React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useContext, useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { TaggedNostrEvent } from "@snort/system";
|
import { TaggedNostrEvent } from "@snort/system";
|
||||||
import { SnortContext } from "@snort/system-react";
|
import { SnortContext } from "@snort/system-react";
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./Relay.css";
|
import "./Relay.css";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { RelaySettings } from "@snort/system";
|
import { RelaySettings } from "@snort/system";
|
||||||
import { unixNowMs } from "@snort/shared";
|
import { unixNowMs } from "@snort/shared";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
import { FileExtensionRegex } from "Const";
|
import { FileExtensionRegex } from "Const";
|
||||||
import Reveal from "Element/Reveal";
|
import Reveal from "Element/Reveal";
|
||||||
|
@ -2,7 +2,7 @@ import "./RootTabs.css";
|
|||||||
import { useState, ReactNode, useEffect } from "react";
|
import { useState, ReactNode, useEffect } from "react";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { Menu, MenuItem } from "@szhsin/react-menu";
|
import { Menu, MenuItem } from "@szhsin/react-menu";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
import useLogin from "Hooks/useLogin";
|
import useLogin from "Hooks/useLogin";
|
||||||
import Icon from "Icons/Icon";
|
import Icon from "Icons/Icon";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { HexKey, NostrPrefix } from "@snort/system";
|
import { HexKey, NostrPrefix } from "@snort/system";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
import FollowListBase from "Element/FollowListBase";
|
import FollowListBase from "Element/FollowListBase";
|
||||||
import PageSpinner from "Element/PageSpinner";
|
import PageSpinner from "Element/PageSpinner";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import "./Timeline.css";
|
import "./Timeline.css";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
import { useInView } from "react-intersection-observer";
|
import { useInView } from "react-intersection-observer";
|
||||||
import { TaggedNostrEvent, EventKind, u256 } from "@snort/system";
|
import { TaggedNostrEvent, EventKind, u256 } from "@snort/system";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./Timeline.css";
|
import "./Timeline.css";
|
||||||
import { ReactNode, useCallback, useContext, useMemo, useState, useSyncExternalStore } from "react";
|
import { ReactNode, useCallback, useContext, useMemo, useState, useSyncExternalStore } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { TaggedNostrEvent, EventKind, u256, NostrEvent, NostrLink } from "@snort/system";
|
import { TaggedNostrEvent, EventKind, u256, NostrEvent, NostrLink } from "@snort/system";
|
||||||
import { unixNow } from "@snort/shared";
|
import { unixNow } from "@snort/shared";
|
||||||
import { SnortContext } from "@snort/system-react";
|
import { SnortContext } from "@snort/system-react";
|
||||||
|
@ -4,7 +4,7 @@ import { NostrEvent, NostrLink } from "@snort/system";
|
|||||||
|
|
||||||
import { ProxyImg } from "Element/ProxyImg";
|
import { ProxyImg } from "Element/ProxyImg";
|
||||||
import ProfileImage from "Element/ProfileImage";
|
import ProfileImage from "Element/ProfileImage";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
export default function ZapstrEmbed({ ev }: { ev: NostrEvent }) {
|
export default function ZapstrEmbed({ ev }: { ev: NostrEvent }) {
|
||||||
const media = ev.tags.find(a => a[0] === "media");
|
const media = ev.tags.find(a => a[0] === "media");
|
||||||
|
@ -86,6 +86,7 @@ export class MultiAccountStore extends ExternalStore<LoginSession> {
|
|||||||
};
|
};
|
||||||
v.extraChats ??= [];
|
v.extraChats ??= [];
|
||||||
}
|
}
|
||||||
|
this.#loadIrisKeyIfExists();
|
||||||
}
|
}
|
||||||
|
|
||||||
getSessions() {
|
getSessions() {
|
||||||
@ -217,6 +218,23 @@ export class MultiAccountStore extends ExternalStore<LoginSession> {
|
|||||||
return { ...s };
|
return { ...s };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async #loadIrisKeyIfExists() {
|
||||||
|
try {
|
||||||
|
const irisKeyJSON = window.localStorage.getItem('iris.myKey');
|
||||||
|
if (irisKeyJSON) {
|
||||||
|
const irisKeyObj = JSON.parse(irisKeyJSON);
|
||||||
|
if (irisKeyObj.priv) {
|
||||||
|
const privateKey = await PinEncrypted.create(irisKeyObj.priv, '1234');
|
||||||
|
this.loginWithPrivateKey(privateKey);
|
||||||
|
window.localStorage.removeItem('iris.myKey');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to load iris key", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#migrate() {
|
#migrate() {
|
||||||
let didMigrate = false;
|
let didMigrate = false;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import "./Deck.css";
|
import "./Deck.css";
|
||||||
import { CSSProperties, createContext, useContext, useEffect, useState } from "react";
|
import { CSSProperties, createContext, useContext, useEffect, useState } from "react";
|
||||||
import { Outlet, useNavigate } from "react-router-dom";
|
import { Outlet, useNavigate } from "react-router-dom";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { NostrLink } from "@snort/system";
|
import { NostrLink } from "@snort/system";
|
||||||
|
|
||||||
import { DeckNav } from "Element/Deck/Nav";
|
import { DeckNav } from "Element/Deck/Nav";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { HexKey } from "@snort/system";
|
import { HexKey } from "@snort/system";
|
||||||
|
|
||||||
import { ApiHost, KieranPubKey, SnortPubKey } from "Const";
|
import { ApiHost, KieranPubKey, SnortPubKey } from "Const";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { db } from "Db";
|
import { db } from "Db";
|
||||||
import AsyncButton from "Element/AsyncButton";
|
import AsyncButton from "Element/AsyncButton";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useRouteError } from "react-router-dom";
|
import { useRouteError } from "react-router-dom";
|
||||||
|
|
||||||
const ErrorPage = () => {
|
const ErrorPage = () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
import Timeline from "Element/Timeline";
|
import Timeline from "Element/Timeline";
|
||||||
import useEventPublisher from "Hooks/useEventPublisher";
|
import useEventPublisher from "Hooks/useEventPublisher";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { KieranPubKey } from "Const";
|
import { KieranPubKey } from "Const";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { TLVEntryType, encodeTLVEntries, NostrPrefix } from "@snort/system";
|
import { TLVEntryType, encodeTLVEntries, NostrPrefix } from "@snort/system";
|
||||||
import { bech32ToHex } from "SnortUtils";
|
import { bech32ToHex } from "SnortUtils";
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ function LogoHeader() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Link to="/" className="logo">
|
<Link to="/" className="logo">
|
||||||
<h1>Snort</h1>
|
<h1>{process.env.APP_NAME}</h1>
|
||||||
{currentSubscription && (
|
{currentSubscription && (
|
||||||
<small className="flex">
|
<small className="flex">
|
||||||
<Icon name="diamond" size={10} className="mr5" />
|
<Icon name="diamond" size={10} className="mr5" />
|
||||||
|
@ -283,7 +283,7 @@ export default function LoginPage() {
|
|||||||
<div>
|
<div>
|
||||||
<div className="login-container">
|
<div className="login-container">
|
||||||
<h1 className="logo" onClick={() => navigate("/")}>
|
<h1 className="logo" onClick={() => navigate("/")}>
|
||||||
Snort
|
{process.env.APP_NAME}
|
||||||
</h1>
|
</h1>
|
||||||
<h1 dir="auto">
|
<h1 dir="auto">
|
||||||
<FormattedMessage defaultMessage="Login" description="Login header" />
|
<FormattedMessage defaultMessage="Login" description="Login header" />
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
import { ApiHost } from "Const";
|
import { ApiHost } from "Const";
|
||||||
import Nip5Service from "Element/Nip5Service";
|
import Nip5Service from "Element/Nip5Service";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { NostrPrefix, tryParseNostrLink } from "@snort/system";
|
import { NostrPrefix, tryParseNostrLink } from "@snort/system";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
|
||||||
import Spinner from "Icons/Spinner";
|
import Spinner from "Icons/Spinner";
|
||||||
@ -24,7 +24,7 @@ export default function NostrLinkHandler() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const pubkey = await getNip05PubKey(`${link}@snort.social`);
|
const pubkey = await getNip05PubKey(`${link}@${process.env.NIP05_DOMAIN}`);
|
||||||
if (pubkey) {
|
if (pubkey) {
|
||||||
navigate(profileLink(pubkey));
|
navigate(profileLink(pubkey));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./ProfilePage.css";
|
import "./ProfilePage.css";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
encodeTLV,
|
encodeTLV,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { Link, Outlet, RouteObject, useParams } from "react-router-dom";
|
import { Link, Outlet, RouteObject, useParams } from "react-router-dom";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { unixNow } from "@snort/shared";
|
import { unixNow } from "@snort/shared";
|
||||||
import { NostrLink } from "@snort/system";
|
import { NostrLink } from "@snort/system";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Outlet, RouteObject, useNavigate } from "react-router-dom";
|
import { Outlet, RouteObject, useNavigate } from "react-router-dom";
|
||||||
import SettingsIndex from "Pages/settings/Root";
|
import SettingsIndex from "Pages/settings/Root";
|
||||||
import Profile from "Pages/settings/Profile";
|
import Profile from "Pages/settings/Profile";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useUserProfile } from "@snort/system-react";
|
import { useUserProfile } from "@snort/system-react";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import Logo from "Element/Logo";
|
import Logo from "Element/Logo";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import ProfilePreview from "Element/ProfilePreview";
|
import ProfilePreview from "Element/ProfilePreview";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import "./Keys.css";
|
import "./Keys.css";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { encodeTLV, NostrPrefix, PinEncrypted } from "@snort/system";
|
import { encodeTLV, NostrPrefix, PinEncrypted } from "@snort/system";
|
||||||
|
|
||||||
import Copy from "Element/Copy";
|
import Copy from "Element/Copy";
|
||||||
|
@ -3,7 +3,7 @@ import useLogin from "Hooks/useLogin";
|
|||||||
import { setAppData } from "Login";
|
import { setAppData } from "Login";
|
||||||
import { appendDedupe } from "SnortUtils";
|
import { appendDedupe } from "SnortUtils";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
|
|
||||||
export function ModerationSettings() {
|
export function ModerationSettings() {
|
||||||
const login = useLogin();
|
const login = useLogin();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./Profile.css";
|
import "./Profile.css";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { mapEventToProfile } from "@snort/system";
|
import { mapEventToProfile } from "@snort/system";
|
||||||
import { useUserProfile } from "@snort/system-react";
|
import { useUserProfile } from "@snort/system-react";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import ProfilePreview from "Element/ProfilePreview";
|
import ProfilePreview from "Element/ProfilePreview";
|
||||||
import useRelayState from "Feed/RelayState";
|
import useRelayState from "Feed/RelayState";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { unixNowMs } from "@snort/shared";
|
import { unixNowMs } from "@snort/shared";
|
||||||
|
|
||||||
import { randomSample } from "SnortUtils";
|
import { randomSample } from "SnortUtils";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./Root.css";
|
import "./Root.css";
|
||||||
import { useEffect, useMemo } from "react";
|
import { useEffect, useMemo } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Outlet, useLocation, useNavigate } from "react-router-dom";
|
import { Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||||
import Icon from "Icons/Icon";
|
import Icon from "Icons/Icon";
|
||||||
import { LoginStore, logout } from "Login";
|
import { LoginStore, logout } from "Login";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import "./WalletSettings.css";
|
import "./WalletSettings.css";
|
||||||
import LndLogo from "lnd-logo.png";
|
import LndLogo from "lnd-logo.png";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Link, RouteObject, useNavigate } from "react-router-dom";
|
import { Link, RouteObject, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import BlueWallet from "Icons/BlueWallet";
|
import BlueWallet from "Icons/BlueWallet";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { ApiHost } from "Const";
|
import { ApiHost } from "Const";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Outlet, RouteObject, useNavigate } from "react-router-dom";
|
import { Outlet, RouteObject, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import ListHandles from "./ListHandles";
|
import ListHandles from "./ListHandles";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import PageSpinner from "Element/PageSpinner";
|
import PageSpinner from "Element/PageSpinner";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { RouteObject } from "react-router-dom";
|
import { RouteObject } from "react-router-dom";
|
||||||
|
|
||||||
import { formatShort } from "Number";
|
import { formatShort } from "Number";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { BaseUITask } from "Tasks";
|
import { BaseUITask } from "Tasks";
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FormattedMessage } from "react-intl";
|
import FormattedMessage from "Element/FormattedMessage";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { MetadataCache } from "@snort/system";
|
import { MetadataCache } from "@snort/system";
|
||||||
import { BaseUITask } from "Tasks";
|
import { BaseUITask } from "Tasks";
|
||||||
|
@ -9,6 +9,8 @@ const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
|||||||
const CopyPlugin = require("copy-webpack-plugin");
|
const CopyPlugin = require("copy-webpack-plugin");
|
||||||
const WorkboxPlugin = require("workbox-webpack-plugin");
|
const WorkboxPlugin = require("workbox-webpack-plugin");
|
||||||
const IntlTsTransformer = require("@formatjs/ts-transformer");
|
const IntlTsTransformer = require("@formatjs/ts-transformer");
|
||||||
|
const { DefinePlugin } = require('webpack');
|
||||||
|
const appConfig = require('config');
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV == "production";
|
const isProduction = process.env.NODE_ENV == "production";
|
||||||
|
|
||||||
@ -47,8 +49,11 @@ const config = {
|
|||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: "public/index.html",
|
template: "public/index.html",
|
||||||
favicon: "public/favicon.ico",
|
favicon: appConfig.get('favicon'),
|
||||||
excludeChunks: ["pow", "bench"],
|
excludeChunks: ["pow", "bench"],
|
||||||
|
templateParameters: {
|
||||||
|
appTitle: appConfig.get('appTitle'),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
filename: "bench.html",
|
filename: "bench.html",
|
||||||
@ -69,6 +74,11 @@ const config = {
|
|||||||
swSrc: "./src/service-worker.ts",
|
swSrc: "./src/service-worker.ts",
|
||||||
})
|
})
|
||||||
: false,
|
: false,
|
||||||
|
new DefinePlugin({
|
||||||
|
"process.env.APP_NAME": JSON.stringify(appConfig.get('appName')),
|
||||||
|
"process.env.APP_NAME_CAPITALIZED": JSON.stringify(appConfig.get('appNameCapitalized')),
|
||||||
|
"process.env.NIP05_DOMAIN": JSON.stringify(appConfig.get('nip05Domain')),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -2709,6 +2709,7 @@ __metadata:
|
|||||||
"@webpack-cli/generators": ^3.0.4
|
"@webpack-cli/generators": ^3.0.4
|
||||||
"@webscopeio/react-textarea-autocomplete": ^4.9.2
|
"@webscopeio/react-textarea-autocomplete": ^4.9.2
|
||||||
babel-loader: ^9.1.3
|
babel-loader: ^9.1.3
|
||||||
|
config: ^3.3.9
|
||||||
copy-webpack-plugin: ^11.0.0
|
copy-webpack-plugin: ^11.0.0
|
||||||
css-loader: ^6.7.3
|
css-loader: ^6.7.3
|
||||||
css-minimizer-webpack-plugin: ^5.0.0
|
css-minimizer-webpack-plugin: ^5.0.0
|
||||||
@ -5330,6 +5331,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"config@npm:^3.3.9":
|
||||||
|
version: 3.3.9
|
||||||
|
resolution: "config@npm:3.3.9"
|
||||||
|
dependencies:
|
||||||
|
json5: ^2.2.3
|
||||||
|
checksum: 2c29e40be22274462769670a4b69fcbcad2d3049eb15030073e410d32c892ef29e0c879a3d68ef92ddd572c516e4f65a11bb6458f680a44ceb0f051bcd3d97ff
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"connect-history-api-fallback@npm:^2.0.0":
|
"connect-history-api-fallback@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "connect-history-api-fallback@npm:2.0.0"
|
resolution: "connect-history-api-fallback@npm:2.0.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user